From 406c72614143474a85b799eb4825741d118e7400 Mon Sep 17 00:00:00 2001 From: liquidiert Date: Sat, 28 Nov 2020 19:34:11 +0100 Subject: [PATCH] intermediate commit - removed py cache and env --- .../algorithm_management.cpython-38.pyc | Bin 1932 -> 0 bytes __pycache__/game_management.cpython-38.pyc | Bin 1120 -> 0 bytes __pycache__/main.cpython-38.pyc | Bin 422 -> 0 bytes env/bin/Activate.ps1 | 241 - env/bin/activate | 76 - env/bin/activate.csh | 37 - env/bin/activate.fish | 75 - env/bin/autopep8 | 12 - env/bin/easy_install | 8 - env/bin/easy_install-3.8 | 8 - env/bin/epylint | 8 - env/bin/isort | 8 - env/bin/pip | 8 - env/bin/pip3 | 8 - env/bin/pip3.8 | 8 - env/bin/pycodestyle | 8 - env/bin/pylint | 8 - env/bin/pyreverse | 8 - env/bin/python | 1 - env/bin/python3 | 1 - env/bin/python3.8 | 1 - env/bin/symilar | 8 - env/bin/uvicorn | 8 - .../__pycache__/autopep8.cpython-38.pyc | Bin 101119 -> 0 bytes .../__pycache__/easy_install.cpython-38.pyc | Bin 281 -> 0 bytes .../__pycache__/mccabe.cpython-38.pyc | Bin 11251 -> 0 bytes .../__pycache__/pycodestyle.cpython-38.pyc | Bin 72651 -> 0 bytes .../__pycache__/six.cpython-38.pyc | Bin 26921 -> 0 bytes .../astroid-2.4.2.dist-info/COPYING | 339 - .../astroid-2.4.2.dist-info/COPYING.LESSER | 510 -- .../astroid-2.4.2.dist-info/INSTALLER | 1 - .../astroid-2.4.2.dist-info/METADATA | 118 - .../astroid-2.4.2.dist-info/RECORD | 151 - .../astroid-2.4.2.dist-info/WHEEL | 5 - .../astroid-2.4.2.dist-info/top_level.txt | 1 - .../site-packages/astroid/__init__.py | 168 - .../site-packages/astroid/__pkginfo__.py | 56 - .../__pycache__/__init__.cpython-38.pyc | Bin 4479 -> 0 bytes .../__pycache__/__pkginfo__.cpython-38.pyc | Bin 1427 -> 0 bytes .../astroid/__pycache__/_ast.cpython-38.pyc | Bin 3107 -> 0 bytes .../__pycache__/arguments.cpython-38.pyc | Bin 7669 -> 0 bytes .../__pycache__/as_string.cpython-38.pyc | Bin 26097 -> 0 bytes .../astroid/__pycache__/bases.cpython-38.pyc | Bin 15940 -> 0 bytes .../__pycache__/builder.cpython-38.pyc | Bin 12905 -> 0 bytes .../__pycache__/context.cpython-38.pyc | Bin 4347 -> 0 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 3601 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 9211 -> 0 bytes .../__pycache__/helpers.cpython-38.pyc | Bin 7417 -> 0 bytes .../__pycache__/inference.cpython-38.pyc | Bin 22367 -> 0 bytes .../__pycache__/manager.cpython-38.pyc | Bin 9805 -> 0 bytes .../astroid/__pycache__/mixins.cpython-38.pyc | Bin 5891 -> 0 bytes .../__pycache__/modutils.cpython-38.pyc | Bin 17104 -> 0 bytes .../__pycache__/node_classes.cpython-38.pyc | Bin 115716 -> 0 bytes .../astroid/__pycache__/nodes.cpython-38.pyc | Bin 2099 -> 0 bytes .../__pycache__/objects.cpython-38.pyc | Bin 9719 -> 0 bytes .../__pycache__/protocols.cpython-38.pyc | Bin 17021 -> 0 bytes .../__pycache__/raw_building.cpython-38.pyc | Bin 11673 -> 0 bytes .../__pycache__/rebuilder.cpython-38.pyc | Bin 35577 -> 0 bytes .../__pycache__/scoped_nodes.cpython-38.pyc | Bin 69472 -> 0 bytes .../__pycache__/test_utils.cpython-38.pyc | Bin 2512 -> 0 bytes .../__pycache__/transforms.cpython-38.pyc | Bin 3458 -> 0 bytes .../astroid/__pycache__/util.cpython-38.pyc | Bin 5826 -> 0 bytes .../python3.8/site-packages/astroid/_ast.py | 131 - .../site-packages/astroid/arguments.py | 300 - .../site-packages/astroid/as_string.py | 631 -- .../python3.8/site-packages/astroid/bases.py | 548 -- .../__pycache__/brain_argparse.cpython-38.pyc | Bin 1105 -> 0 bytes .../__pycache__/brain_attrs.cpython-38.pyc | Bin 1602 -> 0 bytes .../__pycache__/brain_boto3.cpython-38.pyc | Bin 933 -> 0 bytes .../brain_builtin_inference.cpython-38.pyc | Bin 20676 -> 0 bytes .../brain_collections.cpython-38.pyc | Bin 2531 -> 0 bytes .../__pycache__/brain_crypt.cpython-38.pyc | Bin 873 -> 0 bytes .../__pycache__/brain_curses.cpython-38.pyc | Bin 3389 -> 0 bytes .../brain_dataclasses.cpython-38.pyc | Bin 1305 -> 0 bytes .../__pycache__/brain_dateutil.cpython-38.pyc | Bin 707 -> 0 bytes .../__pycache__/brain_fstrings.cpython-38.pyc | Bin 1587 -> 0 bytes .../brain_functools.cpython-38.pyc | Bin 4683 -> 0 bytes .../brain/__pycache__/brain_gi.cpython-38.pyc | Bin 4443 -> 0 bytes .../__pycache__/brain_hashlib.cpython-38.pyc | Bin 1967 -> 0 bytes .../__pycache__/brain_http.cpython-38.pyc | Bin 10524 -> 0 bytes .../brain/__pycache__/brain_io.cpython-38.pyc | Bin 1339 -> 0 bytes .../brain_mechanize.cpython-38.pyc | Bin 741 -> 0 bytes .../brain_multiprocessing.cpython-38.pyc | Bin 2559 -> 0 bytes .../brain_namedtuple_enum.cpython-38.pyc | Bin 11690 -> 0 bytes .../__pycache__/brain_nose.cpython-38.pyc | Bin 2094 -> 0 bytes ...rain_numpy_core_fromnumeric.cpython-38.pyc | Bin 652 -> 0 bytes ...in_numpy_core_function_base.cpython-38.pyc | Bin 1046 -> 0 bytes ...brain_numpy_core_multiarray.cpython-38.pyc | Bin 3258 -> 0 bytes .../brain_numpy_core_numeric.cpython-38.pyc | Bin 1290 -> 0 bytes ...ain_numpy_core_numerictypes.cpython-38.pyc | Bin 7754 -> 0 bytes .../brain_numpy_core_umath.cpython-38.pyc | Bin 4396 -> 0 bytes .../brain_numpy_ndarray.cpython-38.pyc | Bin 8391 -> 0 bytes .../brain_numpy_random_mtrand.cpython-38.pyc | Bin 3260 -> 0 bytes .../brain_numpy_utils.cpython-38.pyc | Bin 1885 -> 0 bytes .../brain_pkg_resources.cpython-38.pyc | Bin 2210 -> 0 bytes .../__pycache__/brain_pytest.cpython-38.pyc | Bin 2182 -> 0 bytes .../brain/__pycache__/brain_qt.cpython-38.pyc | Bin 2120 -> 0 bytes .../__pycache__/brain_random.cpython-38.pyc | Bin 2210 -> 0 bytes .../brain/__pycache__/brain_re.cpython-38.pyc | Bin 1089 -> 0 bytes .../brain_responses.cpython-38.pyc | Bin 1794 -> 0 bytes .../brain_scipy_signal.cpython-38.pyc | Bin 2207 -> 0 bytes .../__pycache__/brain_six.cpython-38.pyc | Bin 5589 -> 0 bytes .../__pycache__/brain_ssl.cpython-38.pyc | Bin 3621 -> 0 bytes .../brain_subprocess.cpython-38.pyc | Bin 4217 -> 0 bytes .../brain_threading.cpython-38.pyc | Bin 768 -> 0 bytes .../__pycache__/brain_typing.cpython-38.pyc | Bin 2376 -> 0 bytes .../__pycache__/brain_uuid.cpython-38.pyc | Bin 658 -> 0 bytes .../astroid/brain/brain_argparse.py | 33 - .../astroid/brain/brain_attrs.py | 65 - .../astroid/brain/brain_boto3.py | 28 - .../astroid/brain/brain_builtin_inference.py | 873 --- .../astroid/brain/brain_collections.py | 75 - .../astroid/brain/brain_crypt.py | 26 - .../astroid/brain/brain_curses.py | 179 - .../astroid/brain/brain_dataclasses.py | 50 - .../astroid/brain/brain_dateutil.py | 28 - .../astroid/brain/brain_fstrings.py | 51 - .../astroid/brain/brain_functools.py | 159 - .../site-packages/astroid/brain/brain_gi.py | 253 - .../astroid/brain/brain_hashlib.py | 69 - .../site-packages/astroid/brain/brain_http.py | 211 - .../site-packages/astroid/brain/brain_io.py | 45 - .../astroid/brain/brain_mechanize.py | 29 - .../astroid/brain/brain_multiprocessing.py | 107 - .../astroid/brain/brain_namedtuple_enum.py | 455 -- .../site-packages/astroid/brain/brain_nose.py | 77 - .../brain/brain_numpy_core_fromnumeric.py | 23 - .../brain/brain_numpy_core_function_base.py | 29 - .../brain/brain_numpy_core_multiarray.py | 92 - .../astroid/brain/brain_numpy_core_numeric.py | 43 - .../brain/brain_numpy_core_numerictypes.py | 254 - .../astroid/brain/brain_numpy_core_umath.py | 147 - .../astroid/brain/brain_numpy_ndarray.py | 153 - .../brain/brain_numpy_random_mtrand.py | 70 - .../astroid/brain/brain_numpy_utils.py | 65 - .../astroid/brain/brain_pkg_resources.py | 75 - .../astroid/brain/brain_pytest.py | 88 - .../site-packages/astroid/brain/brain_qt.py | 83 - .../astroid/brain/brain_random.py | 75 - .../site-packages/astroid/brain/brain_re.py | 36 - .../astroid/brain/brain_responses.py | 73 - .../astroid/brain/brain_scipy_signal.py | 89 - .../site-packages/astroid/brain/brain_six.py | 201 - .../site-packages/astroid/brain/brain_ssl.py | 75 - .../astroid/brain/brain_subprocess.py | 146 - .../astroid/brain/brain_threading.py | 31 - .../astroid/brain/brain_typing.py | 96 - .../site-packages/astroid/brain/brain_uuid.py | 20 - .../site-packages/astroid/builder.py | 455 -- .../site-packages/astroid/context.py | 179 - .../site-packages/astroid/decorators.py | 142 - .../site-packages/astroid/exceptions.py | 230 - .../site-packages/astroid/helpers.py | 282 - .../site-packages/astroid/inference.py | 994 --- .../astroid/interpreter/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 201 -> 0 bytes .../__pycache__/dunder_lookup.cpython-38.pyc | Bin 2156 -> 0 bytes .../__pycache__/objectmodel.cpython-38.pyc | Bin 26957 -> 0 bytes .../astroid/interpreter/_import/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 209 -> 0 bytes .../_import/__pycache__/spec.cpython-38.pyc | Bin 9411 -> 0 bytes .../_import/__pycache__/util.cpython-38.pyc | Bin 429 -> 0 bytes .../astroid/interpreter/_import/spec.py | 346 - .../astroid/interpreter/_import/util.py | 10 - .../astroid/interpreter/dunder_lookup.py | 66 - .../astroid/interpreter/objectmodel.py | 801 --- .../site-packages/astroid/manager.py | 350 - .../python3.8/site-packages/astroid/mixins.py | 160 - .../site-packages/astroid/modutils.py | 690 -- .../site-packages/astroid/node_classes.py | 4862 -------------- .../python3.8/site-packages/astroid/nodes.py | 176 - .../site-packages/astroid/objects.py | 314 - .../site-packages/astroid/protocols.py | 780 --- .../site-packages/astroid/raw_building.py | 483 -- .../site-packages/astroid/rebuilder.py | 1010 --- .../site-packages/astroid/scoped_nodes.py | 2927 --------- .../site-packages/astroid/test_utils.py | 73 - .../site-packages/astroid/transforms.py | 90 - .../python3.8/site-packages/astroid/util.py | 164 - .../autopep8-1.5.4.egg-info/PKG-INFO | 451 -- .../autopep8-1.5.4.egg-info/SOURCES.txt | 25 - .../dependency_links.txt | 1 - .../autopep8-1.5.4.egg-info/entry_points.txt | 3 - .../installed-files.txt | 10 - .../autopep8-1.5.4.egg-info/not-zip-safe | 1 - .../autopep8-1.5.4.egg-info/requires.txt | 2 - .../autopep8-1.5.4.egg-info/top_level.txt | 1 - env/lib/python3.8/site-packages/autopep8.py | 4514 ------------- .../click-7.1.2.dist-info/INSTALLER | 1 - .../click-7.1.2.dist-info/LICENSE.rst | 28 - .../click-7.1.2.dist-info/METADATA | 102 - .../click-7.1.2.dist-info/RECORD | 40 - .../site-packages/click-7.1.2.dist-info/WHEEL | 6 - .../click-7.1.2.dist-info/top_level.txt | 1 - .../python3.8/site-packages/click/__init__.py | 79 - .../click/__pycache__/__init__.cpython-38.pyc | Bin 2746 -> 0 bytes .../__pycache__/_bashcomplete.cpython-38.pyc | Bin 10035 -> 0 bytes .../click/__pycache__/_compat.cpython-38.pyc | Bin 18860 -> 0 bytes .../__pycache__/_termui_impl.cpython-38.pyc | Bin 14270 -> 0 bytes .../__pycache__/_textwrap.cpython-38.pyc | Bin 1317 -> 0 bytes .../__pycache__/_unicodefun.cpython-38.pyc | Bin 3353 -> 0 bytes .../__pycache__/_winconsole.cpython-38.pyc | Bin 9477 -> 0 bytes .../click/__pycache__/core.cpython-38.pyc | Bin 62097 -> 0 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 11567 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 9127 -> 0 bytes .../__pycache__/formatting.cpython-38.pyc | Bin 8775 -> 0 bytes .../click/__pycache__/globals.cpython-38.pyc | Bin 1899 -> 0 bytes .../click/__pycache__/parser.cpython-38.pyc | Bin 11888 -> 0 bytes .../click/__pycache__/termui.cpython-38.pyc | Bin 21665 -> 0 bytes .../click/__pycache__/testing.cpython-38.pyc | Bin 11731 -> 0 bytes .../click/__pycache__/types.cpython-38.pyc | Bin 22307 -> 0 bytes .../click/__pycache__/utils.cpython-38.pyc | Bin 15621 -> 0 bytes .../site-packages/click/_bashcomplete.py | 375 -- .../python3.8/site-packages/click/_compat.py | 786 --- .../site-packages/click/_termui_impl.py | 657 -- .../site-packages/click/_textwrap.py | 37 - .../site-packages/click/_unicodefun.py | 131 - .../site-packages/click/_winconsole.py | 370 -- env/lib/python3.8/site-packages/click/core.py | 2030 ------ .../site-packages/click/decorators.py | 333 - .../site-packages/click/exceptions.py | 253 - .../site-packages/click/formatting.py | 283 - .../python3.8/site-packages/click/globals.py | 47 - .../python3.8/site-packages/click/parser.py | 428 -- .../python3.8/site-packages/click/termui.py | 681 -- .../python3.8/site-packages/click/testing.py | 382 -- .../python3.8/site-packages/click/types.py | 762 --- .../python3.8/site-packages/click/utils.py | 455 -- .../python3.8/site-packages/easy_install.py | 5 - .../fastapi-0.61.2.dist-info/INSTALLER | 1 - .../fastapi-0.61.2.dist-info/LICENSE | 21 - .../fastapi-0.61.2.dist-info/METADATA | 545 -- .../fastapi-0.61.2.dist-info/RECORD | 86 - .../fastapi-0.61.2.dist-info/WHEEL | 4 - .../site-packages/fastapi/__init__.py | 25 - .../__pycache__/__init__.cpython-38.pyc | Bin 928 -> 0 bytes .../__pycache__/applications.cpython-38.pyc | Bin 14214 -> 0 bytes .../__pycache__/background.cpython-38.pyc | Bin 251 -> 0 bytes .../__pycache__/concurrency.cpython-38.pyc | Bin 1564 -> 0 bytes .../__pycache__/datastructures.cpython-38.pyc | Bin 986 -> 0 bytes .../__pycache__/encoders.cpython-38.pyc | Bin 2853 -> 0 bytes .../exception_handlers.cpython-38.pyc | Bin 1076 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 2031 -> 0 bytes .../fastapi/__pycache__/logger.cpython-38.pyc | Bin 246 -> 0 bytes .../param_functions.cpython-38.pyc | Bin 4132 -> 0 bytes .../fastapi/__pycache__/params.cpython-38.pyc | Bin 7274 -> 0 bytes .../__pycache__/requests.cpython-38.pyc | Bin 276 -> 0 bytes .../__pycache__/responses.cpython-38.pyc | Bin 1063 -> 0 bytes .../__pycache__/routing.cpython-38.pyc | Bin 20006 -> 0 bytes .../__pycache__/staticfiles.cpython-38.pyc | Bin 203 -> 0 bytes .../__pycache__/templating.cpython-38.pyc | Bin 205 -> 0 bytes .../__pycache__/testclient.cpython-38.pyc | Bin 200 -> 0 bytes .../fastapi/__pycache__/utils.cpython-38.pyc | Bin 3940 -> 0 bytes .../__pycache__/websockets.cpython-38.pyc | Bin 287 -> 0 bytes .../site-packages/fastapi/applications.py | 710 -- .../site-packages/fastapi/background.py | 1 - .../site-packages/fastapi/concurrency.py | 47 - .../site-packages/fastapi/datastructures.py | 15 - .../fastapi/dependencies/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 202 -> 0 bytes .../__pycache__/models.cpython-38.pyc | Bin 2166 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 18102 -> 0 bytes .../fastapi/dependencies/models.py | 58 - .../fastapi/dependencies/utils.py | 785 --- .../site-packages/fastapi/encoders.py | 148 - .../fastapi/exception_handlers.py | 25 - .../site-packages/fastapi/exceptions.py | 37 - .../python3.8/site-packages/fastapi/logger.py | 3 - .../fastapi/middleware/__init__.py | 1 - .../__pycache__/__init__.cpython-38.pyc | Bin 209 -> 0 bytes .../__pycache__/cors.cpython-38.pyc | Bin 214 -> 0 bytes .../__pycache__/gzip.cpython-38.pyc | Bin 214 -> 0 bytes .../__pycache__/httpsredirect.cpython-38.pyc | Bin 241 -> 0 bytes .../__pycache__/trustedhost.cpython-38.pyc | Bin 235 -> 0 bytes .../__pycache__/wsgi.cpython-38.pyc | Bin 214 -> 0 bytes .../site-packages/fastapi/middleware/cors.py | 1 - .../site-packages/fastapi/middleware/gzip.py | 1 - .../fastapi/middleware/httpsredirect.py | 1 - .../fastapi/middleware/trustedhost.py | 1 - .../site-packages/fastapi/middleware/wsgi.py | 1 - .../site-packages/fastapi/openapi/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 197 -> 0 bytes .../__pycache__/constants.cpython-38.pyc | Bin 383 -> 0 bytes .../openapi/__pycache__/docs.cpython-38.pyc | Bin 5752 -> 0 bytes .../openapi/__pycache__/models.cpython-38.pyc | Bin 14522 -> 0 bytes .../openapi/__pycache__/utils.cpython-38.pyc | Bin 9034 -> 0 bytes .../fastapi/openapi/constants.py | 3 - .../site-packages/fastapi/openapi/docs.py | 177 - .../site-packages/fastapi/openapi/models.py | 351 - .../site-packages/fastapi/openapi/utils.py | 366 -- .../site-packages/fastapi/param_functions.py | 253 - .../python3.8/site-packages/fastapi/params.py | 338 - .../python3.8/site-packages/fastapi/py.typed | 0 .../site-packages/fastapi/requests.py | 2 - .../site-packages/fastapi/responses.py | 23 - .../site-packages/fastapi/routing.py | 1016 --- .../fastapi/security/__init__.py | 17 - .../__pycache__/__init__.cpython-38.pyc | Bin 705 -> 0 bytes .../__pycache__/api_key.cpython-38.pyc | Bin 2684 -> 0 bytes .../security/__pycache__/base.cpython-38.pyc | Bin 484 -> 0 bytes .../security/__pycache__/http.cpython-38.pyc | Bin 4550 -> 0 bytes .../__pycache__/oauth2.cpython-38.pyc | Bin 7541 -> 0 bytes .../open_id_connect_url.cpython-38.pyc | Bin 1343 -> 0 bytes .../security/__pycache__/utils.cpython-38.pyc | Bin 489 -> 0 bytes .../site-packages/fastapi/security/api_key.py | 71 - .../site-packages/fastapi/security/base.py | 6 - .../site-packages/fastapi/security/http.py | 152 - .../site-packages/fastapi/security/oauth2.py | 207 - .../fastapi/security/open_id_connect_url.py | 31 - .../site-packages/fastapi/security/utils.py | 8 - .../site-packages/fastapi/staticfiles.py | 1 - .../site-packages/fastapi/templating.py | 1 - .../site-packages/fastapi/testclient.py | 1 - .../python3.8/site-packages/fastapi/utils.py | 138 - .../site-packages/fastapi/websockets.py | 2 - .../h11-0.11.0.dist-info/INSTALLER | 1 - .../h11-0.11.0.dist-info/LICENSE.txt | 22 - .../h11-0.11.0.dist-info/METADATA | 193 - .../site-packages/h11-0.11.0.dist-info/RECORD | 51 - .../site-packages/h11-0.11.0.dist-info/WHEEL | 6 - .../h11-0.11.0.dist-info/top_level.txt | 1 - .../python3.8/site-packages/h11/__init__.py | 21 - .../h11/__pycache__/__init__.cpython-38.pyc | Bin 503 -> 0 bytes .../h11/__pycache__/_abnf.cpython-38.pyc | Bin 1196 -> 0 bytes .../__pycache__/_connection.cpython-38.pyc | Bin 14513 -> 0 bytes .../h11/__pycache__/_events.cpython-38.pyc | Bin 9124 -> 0 bytes .../h11/__pycache__/_headers.cpython-38.pyc | Bin 4657 -> 0 bytes .../h11/__pycache__/_readers.cpython-38.pyc | Bin 5264 -> 0 bytes .../__pycache__/_receivebuffer.cpython-38.pyc | Bin 2489 -> 0 bytes .../h11/__pycache__/_state.cpython-38.pyc | Bin 3837 -> 0 bytes .../h11/__pycache__/_util.cpython-38.pyc | Bin 3616 -> 0 bytes .../h11/__pycache__/_version.cpython-38.pyc | Bin 207 -> 0 bytes .../h11/__pycache__/_writers.cpython-38.pyc | Bin 4016 -> 0 bytes env/lib/python3.8/site-packages/h11/_abnf.py | 129 - .../site-packages/h11/_connection.py | 586 -- .../python3.8/site-packages/h11/_events.py | 305 - .../python3.8/site-packages/h11/_headers.py | 242 - .../python3.8/site-packages/h11/_readers.py | 226 - .../site-packages/h11/_receivebuffer.py | 112 - env/lib/python3.8/site-packages/h11/_state.py | 307 - env/lib/python3.8/site-packages/h11/_util.py | 142 - .../python3.8/site-packages/h11/_version.py | 16 - .../python3.8/site-packages/h11/_writers.py | 143 - .../site-packages/h11/tests/__init__.py | 0 .../tests/__pycache__/__init__.cpython-38.pyc | Bin 145 -> 0 bytes .../tests/__pycache__/helpers.cpython-38.pyc | Bin 1957 -> 0 bytes .../test_against_stdlib_http.cpython-38.pyc | Bin 3637 -> 0 bytes .../test_connection.cpython-38.pyc | Bin 31180 -> 0 bytes .../__pycache__/test_events.cpython-38.pyc | Bin 3682 -> 0 bytes .../__pycache__/test_headers.cpython-38.pyc | Bin 3064 -> 0 bytes .../__pycache__/test_helpers.cpython-38.pyc | Bin 636 -> 0 bytes .../tests/__pycache__/test_io.cpython-38.pyc | Bin 10983 -> 0 bytes .../test_receivebuffer.cpython-38.pyc | Bin 1437 -> 0 bytes .../__pycache__/test_state.cpython-38.pyc | Bin 4959 -> 0 bytes .../__pycache__/test_util.cpython-38.pyc | Bin 2881 -> 0 bytes .../site-packages/h11/tests/data/test-file | 1 - .../site-packages/h11/tests/helpers.py | 77 - .../h11/tests/test_against_stdlib_http.py | 123 - .../h11/tests/test_connection.py | 1046 --- .../site-packages/h11/tests/test_events.py | 181 - .../site-packages/h11/tests/test_headers.py | 151 - .../site-packages/h11/tests/test_helpers.py | 23 - .../site-packages/h11/tests/test_io.py | 507 -- .../h11/tests/test_receivebuffer.py | 78 - .../site-packages/h11/tests/test_state.py | 250 - .../site-packages/h11/tests/test_util.py | 99 - .../isort-5.6.4.dist-info/INSTALLER | 1 - .../isort-5.6.4.dist-info/LICENSE | 21 - .../isort-5.6.4.dist-info/METADATA | 712 -- .../isort-5.6.4.dist-info/RECORD | 96 - .../site-packages/isort-5.6.4.dist-info/WHEEL | 4 - .../isort-5.6.4.dist-info/entry_points.txt | 9 - .../python3.8/site-packages/isort/__init__.py | 9 - .../python3.8/site-packages/isort/__main__.py | 3 - .../isort/__pycache__/__init__.cpython-38.pyc | Bin 640 -> 0 bytes .../isort/__pycache__/__main__.cpython-38.pyc | Bin 188 -> 0 bytes .../isort/__pycache__/_version.cpython-38.pyc | Bin 208 -> 0 bytes .../isort/__pycache__/api.cpython-38.pyc | Bin 11179 -> 0 bytes .../isort/__pycache__/comments.cpython-38.pyc | Bin 1073 -> 0 bytes .../isort/__pycache__/core.cpython-38.pyc | Bin 7604 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 8238 -> 0 bytes .../isort/__pycache__/format.cpython-38.pyc | Bin 5301 -> 0 bytes .../isort/__pycache__/hooks.cpython-38.pyc | Bin 3146 -> 0 bytes .../isort/__pycache__/io.cpython-38.pyc | Bin 2678 -> 0 bytes .../isort/__pycache__/literal.cpython-38.pyc | Bin 4119 -> 0 bytes .../isort/__pycache__/logo.cpython-38.pyc | Bin 537 -> 0 bytes .../isort/__pycache__/main.cpython-38.pyc | Bin 24774 -> 0 bytes .../isort/__pycache__/output.cpython-38.pyc | Bin 12013 -> 0 bytes .../isort/__pycache__/parse.cpython-38.pyc | Bin 10855 -> 0 bytes .../isort/__pycache__/place.cpython-38.pyc | Bin 4921 -> 0 bytes .../isort/__pycache__/profiles.cpython-38.pyc | Bin 1275 -> 0 bytes .../__pycache__/pylama_isort.cpython-38.pyc | Bin 1459 -> 0 bytes .../isort/__pycache__/sections.cpython-38.pyc | Bin 501 -> 0 bytes .../isort/__pycache__/settings.cpython-38.pyc | Bin 19743 -> 0 bytes .../setuptools_commands.cpython-38.pyc | Bin 2298 -> 0 bytes .../isort/__pycache__/sorting.cpython-38.pyc | Bin 2958 -> 0 bytes .../isort/__pycache__/utils.cpython-38.pyc | Bin 878 -> 0 bytes .../isort/__pycache__/wrap.cpython-38.pyc | Bin 3194 -> 0 bytes .../__pycache__/wrap_modes.cpython-38.pyc | Bin 7245 -> 0 bytes .../site-packages/isort/_future/__init__.py | 12 - .../__pycache__/__init__.cpython-38.pyc | Bin 411 -> 0 bytes .../__pycache__/_dataclasses.cpython-38.pyc | Bin 21748 -> 0 bytes .../isort/_future/_dataclasses.py | 1209 ---- .../isort/_vendored/toml/LICENSE | 27 - .../isort/_vendored/toml/__init__.py | 23 - .../toml/__pycache__/__init__.cpython-38.pyc | Bin 718 -> 0 bytes .../toml/__pycache__/decoder.cpython-38.pyc | Bin 23083 -> 0 bytes .../toml/__pycache__/encoder.cpython-38.pyc | Bin 9390 -> 0 bytes .../toml/__pycache__/ordered.cpython-38.pyc | Bin 916 -> 0 bytes .../toml/__pycache__/tz.cpython-38.pyc | Bin 1135 -> 0 bytes .../isort/_vendored/toml/decoder.py | 1053 --- .../isort/_vendored/toml/encoder.py | 295 - .../isort/_vendored/toml/ordered.py | 13 - .../site-packages/isort/_vendored/toml/tz.py | 21 - .../python3.8/site-packages/isort/_version.py | 1 - env/lib/python3.8/site-packages/isort/api.py | 389 -- .../python3.8/site-packages/isort/comments.py | 32 - env/lib/python3.8/site-packages/isort/core.py | 420 -- .../isort/deprecated/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 198 -> 0 bytes .../__pycache__/finders.cpython-38.pyc | Bin 13551 -> 0 bytes .../site-packages/isort/deprecated/finders.py | 415 -- .../site-packages/isort/exceptions.py | 171 - .../python3.8/site-packages/isort/format.py | 149 - .../python3.8/site-packages/isort/hooks.py | 90 - env/lib/python3.8/site-packages/isort/io.py | 69 - .../python3.8/site-packages/isort/literal.py | 109 - env/lib/python3.8/site-packages/isort/logo.py | 19 - env/lib/python3.8/site-packages/isort/main.py | 1022 --- .../python3.8/site-packages/isort/output.py | 584 -- .../python3.8/site-packages/isort/parse.py | 548 -- .../python3.8/site-packages/isort/place.py | 145 - .../python3.8/site-packages/isort/profiles.py | 68 - .../site-packages/isort/pylama_isort.py | 43 - .../python3.8/site-packages/isort/sections.py | 9 - .../python3.8/site-packages/isort/settings.py | 739 --- .../isort/setuptools_commands.py | 61 - .../python3.8/site-packages/isort/sorting.py | 102 - .../site-packages/isort/stdlibs/__init__.py | 1 - .../__pycache__/__init__.cpython-38.pyc | Bin 341 -> 0 bytes .../stdlibs/__pycache__/all.cpython-38.pyc | Bin 254 -> 0 bytes .../stdlibs/__pycache__/py2.cpython-38.pyc | Bin 235 -> 0 bytes .../stdlibs/__pycache__/py27.cpython-38.pyc | Bin 4189 -> 0 bytes .../stdlibs/__pycache__/py3.cpython-38.pyc | Bin 319 -> 0 bytes .../stdlibs/__pycache__/py35.cpython-38.pyc | Bin 3055 -> 0 bytes .../stdlibs/__pycache__/py36.cpython-38.pyc | Bin 3068 -> 0 bytes .../stdlibs/__pycache__/py37.cpython-38.pyc | Bin 3090 -> 0 bytes .../stdlibs/__pycache__/py38.cpython-38.pyc | Bin 3077 -> 0 bytes .../stdlibs/__pycache__/py39.cpython-38.pyc | Bin 3065 -> 0 bytes .../site-packages/isort/stdlibs/all.py | 3 - .../site-packages/isort/stdlibs/py2.py | 3 - .../site-packages/isort/stdlibs/py27.py | 300 - .../site-packages/isort/stdlibs/py3.py | 3 - .../site-packages/isort/stdlibs/py35.py | 222 - .../site-packages/isort/stdlibs/py36.py | 223 - .../site-packages/isort/stdlibs/py37.py | 224 - .../site-packages/isort/stdlibs/py38.py | 223 - .../site-packages/isort/stdlibs/py39.py | 223 - .../python3.8/site-packages/isort/utils.py | 16 - env/lib/python3.8/site-packages/isort/wrap.py | 131 - .../site-packages/isort/wrap_modes.py | 325 - .../INSTALLER | 1 - .../METADATA | 166 - .../lazy_object_proxy-1.4.3.dist-info/RECORD | 18 - .../lazy_object_proxy-1.4.3.dist-info/WHEEL | 5 - .../top_level.txt | 1 - .../lazy_object_proxy/__init__.py | 23 - .../__pycache__/__init__.cpython-38.pyc | Bin 571 -> 0 bytes .../__pycache__/_version.cpython-38.pyc | Bin 216 -> 0 bytes .../__pycache__/compat.cpython-38.pyc | Bin 406 -> 0 bytes .../__pycache__/simple.cpython-38.pyc | Bin 7773 -> 0 bytes .../__pycache__/slots.cpython-38.pyc | Bin 15221 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 811 -> 0 bytes .../lazy_object_proxy/_version.py | 4 - .../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 - .../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 - env/lib/python3.8/site-packages/mccabe.py | 347 - .../pip-20.1.1.dist-info/INSTALLER | 1 - .../pip-20.1.1.dist-info/LICENSE.txt | 20 - .../pip-20.1.1.dist-info/METADATA | 87 - .../site-packages/pip-20.1.1.dist-info/RECORD | 272 - .../site-packages/pip-20.1.1.dist-info/WHEEL | 6 - .../pip-20.1.1.dist-info/entry_points.txt | 5 - .../pip-20.1.1.dist-info/top_level.txt | 1 - .../python3.8/site-packages/pip/__init__.py | 18 - .../python3.8/site-packages/pip/__main__.py | 26 - .../pip/__pycache__/__init__.cpython-38.pyc | Bin 629 -> 0 bytes .../pip/__pycache__/__main__.cpython-38.pyc | Bin 473 -> 0 bytes .../site-packages/pip/_internal/__init__.py | 17 - .../__pycache__/__init__.cpython-38.pyc | Bin 678 -> 0 bytes .../__pycache__/build_env.cpython-38.pyc | Bin 7391 -> 0 bytes .../__pycache__/cache.cpython-38.pyc | Bin 9090 -> 0 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 10808 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 12536 -> 0 bytes .../__pycache__/locations.cpython-38.pyc | Bin 4579 -> 0 bytes .../_internal/__pycache__/main.cpython-38.pyc | Bin 615 -> 0 bytes .../__pycache__/pyproject.cpython-38.pyc | Bin 3732 -> 0 bytes .../self_outdated_check.cpython-38.pyc | Bin 5493 -> 0 bytes .../__pycache__/wheel_builder.cpython-38.pyc | Bin 6800 -> 0 bytes .../site-packages/pip/_internal/build_env.py | 219 - .../site-packages/pip/_internal/cache.py | 349 - .../pip/_internal/cli/__init__.py | 4 - .../cli/__pycache__/__init__.cpython-38.pyc | Bin 236 -> 0 bytes .../__pycache__/autocompletion.cpython-38.pyc | Bin 4953 -> 0 bytes .../__pycache__/base_command.cpython-38.pyc | Bin 5760 -> 0 bytes .../cli/__pycache__/cmdoptions.cpython-38.pyc | Bin 20537 -> 0 bytes .../command_context.cpython-38.pyc | Bin 1311 -> 0 bytes .../cli/__pycache__/main.cpython-38.pyc | Bin 1416 -> 0 bytes .../__pycache__/main_parser.cpython-38.pyc | Bin 2199 -> 0 bytes .../cli/__pycache__/parser.cpython-38.pyc | Bin 8966 -> 0 bytes .../__pycache__/progress_bars.cpython-38.pyc | Bin 7661 -> 0 bytes .../__pycache__/req_command.cpython-38.pyc | Bin 9918 -> 0 bytes .../cli/__pycache__/spinners.cpython-38.pyc | Bin 4756 -> 0 bytes .../__pycache__/status_codes.cpython-38.pyc | Bin 365 -> 0 bytes .../pip/_internal/cli/autocompletion.py | 164 - .../pip/_internal/cli/base_command.py | 228 - .../pip/_internal/cli/cmdoptions.py | 962 --- .../pip/_internal/cli/command_context.py | 36 - .../site-packages/pip/_internal/cli/main.py | 75 - .../pip/_internal/cli/main_parser.py | 99 - .../site-packages/pip/_internal/cli/parser.py | 266 - .../pip/_internal/cli/progress_bars.py | 277 - .../pip/_internal/cli/req_command.py | 408 -- .../pip/_internal/cli/spinners.py | 173 - .../pip/_internal/cli/status_codes.py | 8 - .../pip/_internal/commands/__init__.py | 122 - .../__pycache__/__init__.cpython-38.pyc | Bin 2966 -> 0 bytes .../commands/__pycache__/cache.cpython-38.pyc | Bin 4394 -> 0 bytes .../commands/__pycache__/check.cpython-38.pyc | Bin 1564 -> 0 bytes .../__pycache__/completion.cpython-38.pyc | Bin 3017 -> 0 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 6555 -> 0 bytes .../commands/__pycache__/debug.cpython-38.pyc | Bin 7322 -> 0 bytes .../__pycache__/download.cpython-38.pyc | Bin 3890 -> 0 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 2867 -> 0 bytes .../commands/__pycache__/hash.cpython-38.pyc | Bin 2000 -> 0 bytes .../commands/__pycache__/help.cpython-38.pyc | Bin 1198 -> 0 bytes .../__pycache__/install.cpython-38.pyc | Bin 16474 -> 0 bytes .../commands/__pycache__/list.cpython-38.pyc | Bin 8470 -> 0 bytes .../__pycache__/search.cpython-38.pyc | Bin 4573 -> 0 bytes .../commands/__pycache__/show.cpython-38.pyc | Bin 6324 -> 0 bytes .../__pycache__/uninstall.cpython-38.pyc | Bin 2786 -> 0 bytes .../commands/__pycache__/wheel.cpython-38.pyc | Bin 5072 -> 0 bytes .../pip/_internal/commands/cache.py | 181 - .../pip/_internal/commands/check.py | 51 - .../pip/_internal/commands/completion.py | 95 - .../pip/_internal/commands/configuration.py | 233 - .../pip/_internal/commands/debug.py | 258 - .../pip/_internal/commands/download.py | 142 - .../pip/_internal/commands/freeze.py | 99 - .../pip/_internal/commands/hash.py | 58 - .../pip/_internal/commands/help.py | 41 - .../pip/_internal/commands/install.py | 717 -- .../pip/_internal/commands/list.py | 301 - .../pip/_internal/commands/search.py | 146 - .../pip/_internal/commands/show.py | 180 - .../pip/_internal/commands/uninstall.py | 89 - .../pip/_internal/commands/wheel.py | 190 - .../pip/_internal/configuration.py | 426 -- .../pip/_internal/distributions/__init__.py | 24 - .../__pycache__/__init__.cpython-38.pyc | Bin 812 -> 0 bytes .../__pycache__/base.cpython-38.pyc | Bin 1928 -> 0 bytes .../__pycache__/installed.cpython-38.pyc | Bin 1208 -> 0 bytes .../__pycache__/sdist.cpython-38.pyc | Bin 3471 -> 0 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 1560 -> 0 bytes .../pip/_internal/distributions/base.py | 45 - .../pip/_internal/distributions/installed.py | 24 - .../pip/_internal/distributions/sdist.py | 104 - .../pip/_internal/distributions/wheel.py | 36 - .../site-packages/pip/_internal/exceptions.py | 308 - .../pip/_internal/index/__init__.py | 2 - .../index/__pycache__/__init__.cpython-38.pyc | Bin 190 -> 0 bytes .../__pycache__/collector.cpython-38.pyc | Bin 17512 -> 0 bytes .../__pycache__/package_finder.cpython-38.pyc | Bin 25793 -> 0 bytes .../pip/_internal/index/collector.py | 661 -- .../pip/_internal/index/package_finder.py | 1016 --- .../site-packages/pip/_internal/locations.py | 200 - .../site-packages/pip/_internal/main.py | 16 - .../pip/_internal/models/__init__.py | 2 - .../__pycache__/__init__.cpython-38.pyc | Bin 224 -> 0 bytes .../__pycache__/candidate.cpython-38.pyc | Bin 1421 -> 0 bytes .../__pycache__/direct_url.cpython-38.pyc | Bin 6498 -> 0 bytes .../__pycache__/format_control.cpython-38.pyc | Bin 2416 -> 0 bytes .../models/__pycache__/index.cpython-38.pyc | Bin 1146 -> 0 bytes .../models/__pycache__/link.cpython-38.pyc | Bin 7088 -> 0 bytes .../models/__pycache__/scheme.cpython-38.pyc | Bin 862 -> 0 bytes .../__pycache__/search_scope.cpython-38.pyc | Bin 3386 -> 0 bytes .../selection_prefs.cpython-38.pyc | Bin 1596 -> 0 bytes .../__pycache__/target_python.cpython-38.pyc | Bin 3249 -> 0 bytes .../models/__pycache__/wheel.cpython-38.pyc | Bin 3192 -> 0 bytes .../pip/_internal/models/candidate.py | 36 - .../pip/_internal/models/direct_url.py | 245 - .../pip/_internal/models/format_control.py | 84 - .../pip/_internal/models/index.py | 31 - .../pip/_internal/models/link.py | 236 - .../pip/_internal/models/scheme.py | 25 - .../pip/_internal/models/search_scope.py | 133 - .../pip/_internal/models/selection_prefs.py | 47 - .../pip/_internal/models/target_python.py | 110 - .../pip/_internal/models/wheel.py | 78 - .../pip/_internal/network/__init__.py | 2 - .../__pycache__/__init__.cpython-38.pyc | Bin 212 -> 0 bytes .../network/__pycache__/auth.cpython-38.pyc | Bin 6985 -> 0 bytes .../network/__pycache__/cache.cpython-38.pyc | Bin 2691 -> 0 bytes .../__pycache__/download.cpython-38.pyc | Bin 4379 -> 0 bytes .../__pycache__/session.cpython-38.pyc | Bin 9217 -> 0 bytes .../network/__pycache__/utils.cpython-38.pyc | Bin 706 -> 0 bytes .../network/__pycache__/xmlrpc.cpython-38.pyc | Bin 1574 -> 0 bytes .../pip/_internal/network/auth.py | 298 - .../pip/_internal/network/cache.py | 81 - .../pip/_internal/network/download.py | 200 - .../pip/_internal/network/session.py | 421 -- .../pip/_internal/network/utils.py | 48 - .../pip/_internal/network/xmlrpc.py | 44 - .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 160 -> 0 bytes .../__pycache__/check.cpython-38.pyc | Bin 3656 -> 0 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 5895 -> 0 bytes .../__pycache__/prepare.cpython-38.pyc | Bin 10893 -> 0 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-38.pyc | Bin 166 -> 0 bytes .../build/__pycache__/metadata.cpython-38.pyc | Bin 1208 -> 0 bytes .../metadata_legacy.cpython-38.pyc | Bin 1950 -> 0 bytes .../build/__pycache__/wheel.cpython-38.pyc | Bin 1306 -> 0 bytes .../__pycache__/wheel_legacy.cpython-38.pyc | Bin 2576 -> 0 bytes .../_internal/operations/build/metadata.py | 40 - .../operations/build/metadata_legacy.py | 77 - .../pip/_internal/operations/build/wheel.py | 46 - .../operations/build/wheel_legacy.py | 115 - .../pip/_internal/operations/check.py | 163 - .../pip/_internal/operations/freeze.py | 272 - .../_internal/operations/install/__init__.py | 2 - .../__pycache__/__init__.cpython-38.pyc | Bin 224 -> 0 bytes .../editable_legacy.cpython-38.pyc | Bin 1302 -> 0 bytes .../install/__pycache__/legacy.cpython-38.pyc | Bin 3322 -> 0 bytes .../install/__pycache__/wheel.cpython-38.pyc | Bin 15071 -> 0 bytes .../operations/install/editable_legacy.py | 52 - .../_internal/operations/install/legacy.py | 142 - .../pip/_internal/operations/install/wheel.py | 631 -- .../pip/_internal/operations/prepare.py | 568 -- .../site-packages/pip/_internal/pyproject.py | 196 - .../pip/_internal/req/__init__.py | 92 - .../req/__pycache__/__init__.cpython-38.pyc | Bin 2194 -> 0 bytes .../__pycache__/constructors.cpython-38.pyc | Bin 10847 -> 0 bytes .../req/__pycache__/req_file.cpython-38.pyc | Bin 12809 -> 0 bytes .../__pycache__/req_install.cpython-38.pyc | Bin 20418 -> 0 bytes .../req/__pycache__/req_set.cpython-38.pyc | Bin 5840 -> 0 bytes .../__pycache__/req_tracker.cpython-38.pyc | Bin 4055 -> 0 bytes .../__pycache__/req_uninstall.cpython-38.pyc | Bin 17460 -> 0 bytes .../pip/_internal/req/constructors.py | 464 -- .../pip/_internal/req/req_file.py | 582 -- .../pip/_internal/req/req_install.py | 850 --- .../pip/_internal/req/req_set.py | 202 - .../pip/_internal/req/req_tracker.py | 151 - .../pip/_internal/req/req_uninstall.py | 649 -- .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 160 -> 0 bytes .../__pycache__/base.cpython-38.pyc | Bin 992 -> 0 bytes .../pip/_internal/resolution/base.py | 20 - .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 167 -> 0 bytes .../__pycache__/resolver.cpython-38.pyc | Bin 11138 -> 0 bytes .../_internal/resolution/legacy/resolver.py | 459 -- .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 171 -> 0 bytes .../__pycache__/base.cpython-38.pyc | Bin 2229 -> 0 bytes .../__pycache__/candidates.cpython-38.pyc | Bin 13326 -> 0 bytes .../__pycache__/factory.cpython-38.pyc | Bin 5261 -> 0 bytes .../__pycache__/provider.cpython-38.pyc | Bin 1915 -> 0 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 4325 -> 0 bytes .../__pycache__/resolver.cpython-38.pyc | Bin 5497 -> 0 bytes .../_internal/resolution/resolvelib/base.py | 52 - .../resolution/resolvelib/candidates.py | 450 -- .../resolution/resolvelib/factory.py | 201 - .../resolution/resolvelib/provider.py | 54 - .../resolution/resolvelib/requirements.py | 119 - .../resolution/resolvelib/resolver.py | 174 - .../pip/_internal/self_outdated_check.py | 242 - .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-38.pyc | Bin 155 -> 0 bytes .../utils/__pycache__/appdirs.cpython-38.pyc | Bin 1345 -> 0 bytes .../utils/__pycache__/compat.cpython-38.pyc | Bin 6038 -> 0 bytes .../compatibility_tags.cpython-38.pyc | Bin 3599 -> 0 bytes .../__pycache__/deprecation.cpython-38.pyc | Bin 2826 -> 0 bytes .../direct_url_helpers.cpython-38.pyc | Bin 2676 -> 0 bytes .../__pycache__/distutils_args.cpython-38.pyc | Bin 1139 -> 0 bytes .../utils/__pycache__/encoding.cpython-38.pyc | Bin 1247 -> 0 bytes .../__pycache__/entrypoints.cpython-38.pyc | Bin 1299 -> 0 bytes .../__pycache__/filesystem.cpython-38.pyc | Bin 5603 -> 0 bytes .../__pycache__/filetypes.cpython-38.pyc | Bin 556 -> 0 bytes .../utils/__pycache__/glibc.cpython-38.pyc | Bin 1708 -> 0 bytes .../utils/__pycache__/hashes.cpython-38.pyc | Bin 4158 -> 0 bytes .../inject_securetransport.cpython-38.pyc | Bin 932 -> 0 bytes .../utils/__pycache__/logging.cpython-38.pyc | Bin 9179 -> 0 bytes .../utils/__pycache__/misc.cpython-38.pyc | Bin 24827 -> 0 bytes .../utils/__pycache__/models.cpython-38.pyc | Bin 1924 -> 0 bytes .../__pycache__/packaging.cpython-38.pyc | Bin 2608 -> 0 bytes .../__pycache__/pkg_resources.cpython-38.pyc | Bin 1822 -> 0 bytes .../setuptools_build.cpython-38.pyc | Bin 2921 -> 0 bytes .../__pycache__/subprocess.cpython-38.pyc | Bin 5590 -> 0 bytes .../utils/__pycache__/temp_dir.cpython-38.pyc | Bin 7037 -> 0 bytes .../utils/__pycache__/typing.cpython-38.pyc | Bin 1437 -> 0 bytes .../__pycache__/unpacking.cpython-38.pyc | Bin 6075 -> 0 bytes .../utils/__pycache__/urls.cpython-38.pyc | Bin 1507 -> 0 bytes .../__pycache__/virtualenv.cpython-38.pyc | Bin 3280 -> 0 bytes .../utils/__pycache__/wheel.cpython-38.pyc | Bin 6332 -> 0 bytes .../pip/_internal/utils/appdirs.py | 44 - .../pip/_internal/utils/compat.py | 270 - .../pip/_internal/utils/compatibility_tags.py | 169 - .../pip/_internal/utils/deprecation.py | 104 - .../pip/_internal/utils/direct_url_helpers.py | 130 - .../pip/_internal/utils/distutils_args.py | 48 - .../pip/_internal/utils/encoding.py | 42 - .../pip/_internal/utils/entrypoints.py | 31 - .../pip/_internal/utils/filesystem.py | 222 - .../pip/_internal/utils/filetypes.py | 16 - .../pip/_internal/utils/glibc.py | 98 - .../pip/_internal/utils/hashes.py | 133 - .../_internal/utils/inject_securetransport.py | 36 - .../pip/_internal/utils/logging.py | 399 -- .../site-packages/pip/_internal/utils/misc.py | 927 --- .../pip/_internal/utils/models.py | 42 - .../pip/_internal/utils/packaging.py | 94 - .../pip/_internal/utils/pkg_resources.py | 44 - .../pip/_internal/utils/setuptools_build.py | 181 - .../pip/_internal/utils/subprocess.py | 277 - .../pip/_internal/utils/temp_dir.py | 271 - .../pip/_internal/utils/typing.py | 38 - .../pip/_internal/utils/unpacking.py | 272 - .../site-packages/pip/_internal/utils/urls.py | 55 - .../pip/_internal/utils/virtualenv.py | 116 - .../pip/_internal/utils/wheel.py | 225 - .../pip/_internal/vcs/__init__.py | 15 - .../vcs/__pycache__/__init__.cpython-38.pyc | Bin 448 -> 0 bytes .../vcs/__pycache__/bazaar.cpython-38.pyc | Bin 3747 -> 0 bytes .../vcs/__pycache__/git.cpython-38.pyc | Bin 9634 -> 0 bytes .../vcs/__pycache__/mercurial.cpython-38.pyc | Bin 5071 -> 0 bytes .../vcs/__pycache__/subversion.cpython-38.pyc | Bin 8519 -> 0 bytes .../__pycache__/versioncontrol.cpython-38.pyc | Bin 19646 -> 0 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 120 - .../site-packages/pip/_internal/vcs/git.py | 394 -- .../pip/_internal/vcs/mercurial.py | 161 - .../pip/_internal/vcs/subversion.py | 334 - .../pip/_internal/vcs/versioncontrol.py | 723 --- .../pip/_internal/wheel_builder.py | 309 - .../site-packages/pip/_vendor/__init__.py | 123 - .../__pycache__/__init__.cpython-38.pyc | Bin 3281 -> 0 bytes .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 566 -- .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 - .../pkg_resources-0.0.0.dist-info/LICENSE.txt | 20 - .../pkg_resources-0.0.0.dist-info/METADATA | 13 - .../pkg_resources-0.0.0.dist-info/RECORD | 38 - .../pkg_resources-0.0.0.dist-info/WHEEL | 6 - .../site-packages/pkg_resources/__init__.py | 3296 ---------- .../__pycache__/__init__.cpython-38.pyc | Bin 100402 -> 0 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 646 -> 0 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 203 -> 0 bytes .../__pycache__/appdirs.cpython-38.pyc | Bin 20556 -> 0 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 201680 -> 0 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 24476 -> 0 bytes .../pkg_resources/_vendor/appdirs.py | 608 -- .../_vendor/packaging/__about__.py | 21 - .../_vendor/packaging/__init__.py | 14 - .../__pycache__/__about__.cpython-38.pyc | Bin 753 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 591 -> 0 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 1027 -> 0 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 2809 -> 0 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8965 -> 0 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 3924 -> 0 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 19833 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 466 -> 0 bytes .../__pycache__/version.cpython-38.pyc | Bin 10680 -> 0 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-38.pyc | Bin 2452 -> 0 bytes .../site-packages/pkg_resources/py31compat.py | 23 - .../pycodestyle-2.6.0.dist-info/INSTALLER | 1 - .../pycodestyle-2.6.0.dist-info/LICENSE | 25 - .../pycodestyle-2.6.0.dist-info/METADATA | 1035 --- .../pycodestyle-2.6.0.dist-info/RECORD | 11 - .../pycodestyle-2.6.0.dist-info/WHEEL | 6 - .../entry_points.txt | 3 - .../namespace_packages.txt | 1 - .../pycodestyle-2.6.0.dist-info/top_level.txt | 1 - .../python3.8/site-packages/pycodestyle.py | 2763 -------- .../pydantic-1.7.2.dist-info/INSTALLER | 1 - .../pydantic-1.7.2.dist-info/LICENSE | 21 - .../pydantic-1.7.2.dist-info/METADATA | 814 --- .../pydantic-1.7.2.dist-info/RECORD | 75 - .../pydantic-1.7.2.dist-info/WHEEL | 5 - .../pydantic-1.7.2.dist-info/top_level.txt | 1 - .../site-packages/pydantic/__init__.py | 103 - .../__pycache__/__init__.cpython-38.pyc | Bin 1765 -> 0 bytes .../class_validators.cpython-38.pyc | Bin 12934 -> 0 bytes .../pydantic/__pycache__/color.cpython-38.pyc | Bin 16766 -> 0 bytes .../__pycache__/dataclasses.cpython-38.pyc | Bin 6616 -> 0 bytes .../__pycache__/datetime_parse.cpython-38.pyc | Bin 6614 -> 0 bytes .../__pycache__/decorator.cpython-38.pyc | Bin 7552 -> 0 bytes .../__pycache__/env_settings.cpython-38.pyc | Bin 5884 -> 0 bytes .../__pycache__/error_wrappers.cpython-38.pyc | Bin 5483 -> 0 bytes .../__pycache__/errors.cpython-38.pyc | Bin 22533 -> 0 bytes .../__pycache__/fields.cpython-38.pyc | Bin 23058 -> 0 bytes .../__pycache__/generics.cpython-38.pyc | Bin 6485 -> 0 bytes .../pydantic/__pycache__/json.cpython-38.pyc | Bin 2721 -> 0 bytes .../pydantic/__pycache__/main.cpython-38.pyc | Bin 27437 -> 0 bytes .../pydantic/__pycache__/mypy.cpython-38.pyc | Bin 22175 -> 0 bytes .../__pycache__/networks.cpython-38.pyc | Bin 13387 -> 0 bytes .../pydantic/__pycache__/parse.cpython-38.pyc | Bin 1737 -> 0 bytes .../__pycache__/schema.cpython-38.pyc | Bin 28552 -> 0 bytes .../pydantic/__pycache__/tools.cpython-38.pyc | Bin 2157 -> 0 bytes .../pydantic/__pycache__/types.cpython-38.pyc | Bin 26592 -> 0 bytes .../__pycache__/typing.cpython-38.pyc | Bin 8515 -> 0 bytes .../pydantic/__pycache__/utils.cpython-38.pyc | Bin 21543 -> 0 bytes .../__pycache__/validators.cpython-38.pyc | Bin 15787 -> 0 bytes .../__pycache__/version.cpython-38.pyc | Bin 1121 -> 0 bytes .../pydantic/class_validators.py | 334 - .../python3.8/site-packages/pydantic/color.py | 488 -- .../site-packages/pydantic/dataclasses.py | 228 - .../site-packages/pydantic/datetime_parse.py | 241 - .../site-packages/pydantic/decorator.py | 249 - .../site-packages/pydantic/env_settings.py | 175 - .../site-packages/pydantic/error_wrappers.py | 151 - .../site-packages/pydantic/errors.py | 577 -- .../site-packages/pydantic/fields.py | 841 --- .../site-packages/pydantic/generics.py | 159 - .../python3.8/site-packages/pydantic/json.py | 86 - .../python3.8/site-packages/pydantic/main.py | 1014 --- .../python3.8/site-packages/pydantic/mypy.py | 687 -- .../site-packages/pydantic/networks.py | 462 -- .../python3.8/site-packages/pydantic/parse.py | 66 - .../python3.8/site-packages/pydantic/py.typed | 0 .../site-packages/pydantic/schema.py | 971 --- .../python3.8/site-packages/pydantic/tools.py | 79 - .../python3.8/site-packages/pydantic/types.py | 874 --- .../site-packages/pydantic/typing.py | 315 - .../python3.8/site-packages/pydantic/utils.py | 634 -- .../site-packages/pydantic/validators.py | 629 -- .../site-packages/pydantic/version.py | 30 - .../pylint-2.6.0.dist-info/COPYING | 340 - .../pylint-2.6.0.dist-info/INSTALLER | 1 - .../pylint-2.6.0.dist-info/METADATA | 205 - .../pylint-2.6.0.dist-info/RECORD | 187 - .../pylint-2.6.0.dist-info/WHEEL | 5 - .../pylint-2.6.0.dist-info/entry_points.txt | 6 - .../pylint-2.6.0.dist-info/top_level.txt | 1 - .../site-packages/pylint/__init__.py | 44 - .../site-packages/pylint/__main__.py | 18 - .../site-packages/pylint/__pkginfo__.py | 102 - .../__pycache__/__init__.cpython-38.pyc | Bin 1112 -> 0 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 326 -> 0 bytes .../__pycache__/__pkginfo__.cpython-38.pyc | Bin 2815 -> 0 bytes .../__pycache__/constants.cpython-38.pyc | Bin 1255 -> 0 bytes .../pylint/__pycache__/epylint.cpython-38.pyc | Bin 4969 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 1331 -> 0 bytes .../pylint/__pycache__/graph.cpython-38.pyc | Bin 5092 -> 0 bytes .../__pycache__/interfaces.cpython-38.pyc | Bin 3741 -> 0 bytes .../__pycache__/testutils.cpython-38.pyc | Bin 20756 -> 0 bytes .../site-packages/pylint/checkers/__init__.py | 67 - .../__pycache__/__init__.cpython-38.pyc | Bin 1602 -> 0 bytes .../checkers/__pycache__/async.cpython-38.pyc | Bin 2729 -> 0 bytes .../checkers/__pycache__/base.cpython-38.pyc | Bin 63728 -> 0 bytes .../__pycache__/base_checker.cpython-38.pyc | Bin 6589 -> 0 bytes .../__pycache__/classes.cpython-38.pyc | Bin 50527 -> 0 bytes .../design_analysis.cpython-38.pyc | Bin 11330 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 16289 -> 0 bytes .../__pycache__/format.cpython-38.pyc | Bin 16005 -> 0 bytes .../__pycache__/imports.cpython-38.pyc | Bin 25328 -> 0 bytes .../__pycache__/logging.cpython-38.pyc | Bin 11674 -> 0 bytes .../checkers/__pycache__/misc.cpython-38.pyc | Bin 5128 -> 0 bytes .../__pycache__/newstyle.cpython-38.pyc | Bin 2458 -> 0 bytes .../__pycache__/python3.cpython-38.pyc | Bin 34955 -> 0 bytes .../__pycache__/raw_metrics.cpython-38.pyc | Bin 3291 -> 0 bytes .../__pycache__/refactoring.cpython-38.pyc | Bin 45699 -> 0 bytes .../__pycache__/similar.cpython-38.pyc | Bin 12301 -> 0 bytes .../__pycache__/spelling.cpython-38.pyc | Bin 9714 -> 0 bytes .../__pycache__/stdlib.cpython-38.pyc | Bin 12457 -> 0 bytes .../__pycache__/strings.cpython-38.pyc | Bin 22106 -> 0 bytes .../__pycache__/typecheck.cpython-38.pyc | Bin 41888 -> 0 bytes .../checkers/__pycache__/utils.cpython-38.pyc | Bin 33108 -> 0 bytes .../__pycache__/variables.cpython-38.pyc | Bin 45304 -> 0 bytes .../site-packages/pylint/checkers/async.py | 90 - .../site-packages/pylint/checkers/base.py | 2507 ------- .../pylint/checkers/base_checker.py | 190 - .../site-packages/pylint/checkers/classes.py | 2093 ------ .../pylint/checkers/design_analysis.py | 500 -- .../pylint/checkers/exceptions.py | 598 -- .../site-packages/pylint/checkers/format.py | 772 --- .../site-packages/pylint/checkers/imports.py | 987 --- .../site-packages/pylint/checkers/logging.py | 415 -- .../site-packages/pylint/checkers/misc.py | 199 - .../site-packages/pylint/checkers/newstyle.py | 133 - .../site-packages/pylint/checkers/python3.py | 1427 ---- .../pylint/checkers/raw_metrics.py | 123 - .../pylint/checkers/refactoring.py | 1574 ----- .../site-packages/pylint/checkers/similar.py | 458 -- .../site-packages/pylint/checkers/spelling.py | 415 -- .../site-packages/pylint/checkers/stdlib.py | 459 -- .../site-packages/pylint/checkers/strings.py | 953 --- .../pylint/checkers/typecheck.py | 1868 ------ .../site-packages/pylint/checkers/utils.py | 1319 ---- .../pylint/checkers/variables.py | 2092 ------ .../site-packages/pylint/config/__init__.py | 117 - .../__pycache__/__init__.cpython-38.pyc | Bin 2637 -> 0 bytes .../configuration_mixin.cpython-38.pyc | Bin 1129 -> 0 bytes .../find_default_config_files.cpython-38.pyc | Bin 1804 -> 0 bytes .../man_help_formatter.cpython-38.pyc | Bin 4115 -> 0 bytes .../config/__pycache__/option.cpython-38.pyc | Bin 4641 -> 0 bytes .../option_manager_mixin.cpython-38.pyc | Bin 11089 -> 0 bytes .../__pycache__/option_parser.cpython-38.pyc | Bin 1830 -> 0 bytes .../options_provider_mixin.cpython-38.pyc | Bin 3781 -> 0 bytes .../pylint/config/configuration_mixin.py | 26 - .../config/find_default_config_files.py | 63 - .../pylint/config/man_help_formatter.py | 139 - .../site-packages/pylint/config/option.py | 164 - .../pylint/config/option_manager_mixin.py | 367 -- .../pylint/config/option_parser.py | 47 - .../pylint/config/options_provider_mixin.py | 111 - .../site-packages/pylint/constants.py | 53 - .../python3.8/site-packages/pylint/epylint.py | 201 - .../site-packages/pylint/exceptions.py | 31 - .../pylint/extensions/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 199 -> 0 bytes .../_check_docs_utils.cpython-38.pyc | Bin 19420 -> 0 bytes .../__pycache__/bad_builtin.cpython-38.pyc | Bin 1945 -> 0 bytes .../broad_try_clause.cpython-38.pyc | Bin 2232 -> 0 bytes .../__pycache__/check_docs.cpython-38.pyc | Bin 663 -> 0 bytes .../__pycache__/check_elif.cpython-38.pyc | Bin 2634 -> 0 bytes .../__pycache__/comparetozero.cpython-38.pyc | Bin 1921 -> 0 bytes .../__pycache__/docparams.cpython-38.pyc | Bin 14626 -> 0 bytes .../__pycache__/docstyle.cpython-38.pyc | Bin 2418 -> 0 bytes .../__pycache__/emptystring.cpython-38.pyc | Bin 1981 -> 0 bytes .../__pycache__/mccabe.cpython-38.pyc | Bin 5616 -> 0 bytes .../overlapping_exceptions.cpython-38.pyc | Bin 2555 -> 0 bytes .../redefined_variable_type.cpython-38.pyc | Bin 3210 -> 0 bytes .../pylint/extensions/_check_docs_utils.py | 808 --- .../pylint/extensions/bad_builtin.py | 71 - .../pylint/extensions/broad_try_clause.py | 74 - .../pylint/extensions/check_docs.py | 23 - .../pylint/extensions/check_elif.py | 79 - .../pylint/extensions/comparetozero.py | 75 - .../pylint/extensions/docparams.py | 540 -- .../pylint/extensions/docstyle.py | 91 - .../pylint/extensions/emptystring.py | 75 - .../site-packages/pylint/extensions/mccabe.py | 199 - .../extensions/overlapping_exceptions.py | 86 - .../extensions/redefined_variable_type.py | 118 - .../python3.8/site-packages/pylint/graph.py | 195 - .../site-packages/pylint/interfaces.py | 103 - .../site-packages/pylint/lint/__init__.py | 91 - .../lint/__pycache__/__init__.cpython-38.pyc | Bin 1023 -> 0 bytes .../__pycache__/check_parallel.cpython-38.pyc | Bin 2607 -> 0 bytes .../lint/__pycache__/pylinter.cpython-38.pyc | Bin 31818 -> 0 bytes .../report_functions.cpython-38.pyc | Bin 2416 -> 0 bytes .../lint/__pycache__/run.cpython-38.pyc | Bin 11436 -> 0 bytes .../lint/__pycache__/utils.cpython-38.pyc | Bin 2169 -> 0 bytes .../pylint/lint/check_parallel.py | 124 - .../site-packages/pylint/lint/pylinter.py | 1166 ---- .../pylint/lint/report_functions.py | 76 - .../site-packages/pylint/lint/run.py | 434 -- .../site-packages/pylint/lint/utils.py | 76 - .../site-packages/pylint/message/__init__.py | 56 - .../__pycache__/__init__.cpython-38.pyc | Bin 684 -> 0 bytes .../__pycache__/message.cpython-38.pyc | Bin 1264 -> 0 bytes .../message_definition.cpython-38.pyc | Bin 3034 -> 0 bytes .../message_definition_store.cpython-38.pyc | Bin 4133 -> 0 bytes .../message_handler_mix_in.cpython-38.pyc | Bin 11159 -> 0 bytes .../message_id_store.cpython-38.pyc | Bin 5007 -> 0 bytes .../site-packages/pylint/message/message.py | 51 - .../pylint/message/message_definition.py | 82 - .../message/message_definition_store.py | 88 - .../pylint/message/message_handler_mix_in.py | 390 -- .../pylint/message/message_id_store.py | 126 - .../pylint/pyreverse/__init__.py | 8 - .../__pycache__/__init__.cpython-38.pyc | Bin 213 -> 0 bytes .../__pycache__/diadefslib.cpython-38.pyc | Bin 7615 -> 0 bytes .../__pycache__/diagrams.cpython-38.pyc | Bin 8723 -> 0 bytes .../__pycache__/inspector.cpython-38.pyc | Bin 10247 -> 0 bytes .../pyreverse/__pycache__/main.cpython-38.pyc | Bin 4567 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 5665 -> 0 bytes .../__pycache__/vcgutils.cpython-38.pyc | Bin 4740 -> 0 bytes .../__pycache__/writer.cpython-38.pyc | Bin 7117 -> 0 bytes .../pylint/pyreverse/diadefslib.py | 240 - .../pylint/pyreverse/diagrams.py | 269 - .../pylint/pyreverse/inspector.py | 361 -- .../site-packages/pylint/pyreverse/main.py | 217 - .../site-packages/pylint/pyreverse/utils.py | 223 - .../pylint/pyreverse/vcgutils.py | 232 - .../site-packages/pylint/pyreverse/writer.py | 217 - .../pylint/reporters/__init__.py | 36 - .../__pycache__/__init__.cpython-38.pyc | Bin 845 -> 0 bytes .../__pycache__/base_reporter.cpython-38.pyc | Bin 2804 -> 0 bytes .../collecting_reporter.cpython-38.pyc | Bin 849 -> 0 bytes .../__pycache__/json_reporter.cpython-38.pyc | Bin 1996 -> 0 bytes .../reports_handler_mix_in.cpython-38.pyc | Bin 3018 -> 0 bytes .../reporters/__pycache__/text.cpython-38.pyc | Bin 7330 -> 0 bytes .../pylint/reporters/base_reporter.py | 64 - .../pylint/reporters/collecting_reporter.py | 19 - .../pylint/reporters/json_reporter.py | 61 - .../reporters/reports_handler_mix_in.py | 77 - .../site-packages/pylint/reporters/text.py | 249 - .../pylint/reporters/ureports/__init__.py | 97 - .../__pycache__/__init__.cpython-38.pyc | Bin 3094 -> 0 bytes .../ureports/__pycache__/nodes.cpython-38.pyc | Bin 5995 -> 0 bytes .../__pycache__/text_writer.cpython-38.pyc | Bin 3690 -> 0 bytes .../pylint/reporters/ureports/nodes.py | 189 - .../pylint/reporters/ureports/text_writer.py | 96 - .../site-packages/pylint/testutils.py | 627 -- .../site-packages/pylint/utils/__init__.py | 69 - .../utils/__pycache__/__init__.cpython-38.pyc | Bin 931 -> 0 bytes .../__pycache__/ast_walker.cpython-38.pyc | Bin 2094 -> 0 bytes .../__pycache__/file_state.cpython-38.pyc | Bin 3866 -> 0 bytes .../__pycache__/pragma_parser.cpython-38.pyc | Bin 3696 -> 0 bytes .../utils/__pycache__/utils.cpython-38.pyc | Bin 11823 -> 0 bytes .../site-packages/pylint/utils/ast_walker.py | 77 - .../site-packages/pylint/utils/file_state.py | 136 - .../pylint/utils/pragma_parser.py | 132 - .../site-packages/pylint/utils/utils.py | 435 -- .../setuptools-44.0.0.dist-info/AUTHORS.txt | 566 -- .../setuptools-44.0.0.dist-info/INSTALLER | 1 - .../setuptools-44.0.0.dist-info/LICENSE.txt | 20 - .../setuptools-44.0.0.dist-info/METADATA | 82 - .../setuptools-44.0.0.dist-info/RECORD | 163 - .../setuptools-44.0.0.dist-info/WHEEL | 6 - .../dependency_links.txt | 2 - .../entry_points.txt | 68 - .../setuptools-44.0.0.dist-info/top_level.txt | 3 - .../setuptools-44.0.0.dist-info/zip-safe | 1 - .../site-packages/setuptools/__init__.py | 228 - .../__pycache__/__init__.cpython-38.pyc | Bin 7768 -> 0 bytes .../_deprecation_warning.cpython-38.pyc | Bin 516 -> 0 bytes .../__pycache__/_imp.cpython-38.pyc | Bin 1890 -> 0 bytes .../__pycache__/archive_util.cpython-38.pyc | Bin 5128 -> 0 bytes .../__pycache__/build_meta.cpython-38.pyc | Bin 8495 -> 0 bytes .../__pycache__/config.cpython-38.pyc | Bin 17896 -> 0 bytes .../__pycache__/dep_util.cpython-38.pyc | Bin 819 -> 0 bytes .../__pycache__/depends.cpython-38.pyc | Bin 5216 -> 0 bytes .../__pycache__/dist.cpython-38.pyc | Bin 42326 -> 0 bytes .../__pycache__/errors.cpython-38.pyc | Bin 816 -> 0 bytes .../__pycache__/extension.cpython-38.pyc | Bin 1961 -> 0 bytes .../__pycache__/glob.cpython-38.pyc | Bin 3733 -> 0 bytes .../__pycache__/installer.cpython-38.pyc | Bin 4102 -> 0 bytes .../__pycache__/launch.cpython-38.pyc | Bin 824 -> 0 bytes .../__pycache__/lib2to3_ex.cpython-38.pyc | Bin 2411 -> 0 bytes .../__pycache__/monkey.cpython-38.pyc | Bin 4644 -> 0 bytes .../__pycache__/msvc.cpython-38.pyc | Bin 39631 -> 0 bytes .../__pycache__/namespaces.cpython-38.pyc | Bin 3616 -> 0 bytes .../__pycache__/package_index.cpython-38.pyc | Bin 32970 -> 0 bytes .../__pycache__/py27compat.cpython-38.pyc | Bin 1749 -> 0 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 1191 -> 0 bytes .../__pycache__/py33compat.cpython-38.pyc | Bin 1408 -> 0 bytes .../__pycache__/py34compat.cpython-38.pyc | Bin 450 -> 0 bytes .../__pycache__/sandbox.cpython-38.pyc | Bin 15536 -> 0 bytes .../__pycache__/site-patch.cpython-38.pyc | Bin 1474 -> 0 bytes .../__pycache__/ssl_support.cpython-38.pyc | Bin 6855 -> 0 bytes .../__pycache__/unicode_utils.cpython-38.pyc | Bin 1151 -> 0 bytes .../__pycache__/version.cpython-38.pyc | Bin 292 -> 0 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 7383 -> 0 bytes .../windows_support.cpython-38.pyc | Bin 989 -> 0 bytes .../setuptools/_deprecation_warning.py | 7 - .../site-packages/setuptools/_imp.py | 73 - .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 154 -> 0 bytes .../__pycache__/ordered_set.cpython-38.pyc | Bin 16412 -> 0 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 201631 -> 0 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 24427 -> 0 bytes .../setuptools/_vendor/ordered_set.py | 488 -- .../setuptools/_vendor/packaging/__about__.py | 27 - .../setuptools/_vendor/packaging/__init__.py | 26 - .../__pycache__/__about__.cpython-38.pyc | Bin 704 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 542 -> 0 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 978 -> 0 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 2760 -> 0 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8927 -> 0 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 3995 -> 0 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 19734 -> 0 bytes .../packaging/__pycache__/tags.cpython-38.pyc | Bin 10811 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 1435 -> 0 bytes .../__pycache__/version.cpython-38.pyc | Bin 12065 -> 0 bytes .../setuptools/_vendor/packaging/_compat.py | 31 - .../_vendor/packaging/_structures.py | 68 - .../setuptools/_vendor/packaging/markers.py | 296 - .../_vendor/packaging/requirements.py | 138 - .../_vendor/packaging/specifiers.py | 749 --- .../setuptools/_vendor/packaging/tags.py | 404 -- .../setuptools/_vendor/packaging/utils.py | 57 - .../setuptools/_vendor/packaging/version.py | 420 -- .../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 | 257 - .../setuptools/command/__init__.py | 17 - .../__pycache__/__init__.cpython-38.pyc | Bin 712 -> 0 bytes .../command/__pycache__/alias.cpython-38.pyc | Bin 2392 -> 0 bytes .../__pycache__/bdist_egg.cpython-38.pyc | Bin 14182 -> 0 bytes .../__pycache__/bdist_rpm.cpython-38.pyc | Bin 1784 -> 0 bytes .../__pycache__/bdist_wininst.cpython-38.pyc | Bin 954 -> 0 bytes .../__pycache__/build_clib.cpython-38.pyc | Bin 2437 -> 0 bytes .../__pycache__/build_ext.cpython-38.pyc | Bin 9895 -> 0 bytes .../__pycache__/build_py.cpython-38.pyc | Bin 8641 -> 0 bytes .../__pycache__/develop.cpython-38.pyc | Bin 6501 -> 0 bytes .../__pycache__/dist_info.cpython-38.pyc | Bin 1361 -> 0 bytes .../__pycache__/easy_install.cpython-38.pyc | Bin 66694 -> 0 bytes .../__pycache__/egg_info.cpython-38.pyc | Bin 21773 -> 0 bytes .../__pycache__/install.cpython-38.pyc | Bin 4016 -> 0 bytes .../install_egg_info.cpython-38.pyc | Bin 2900 -> 0 bytes .../__pycache__/install_lib.cpython-38.pyc | Bin 5083 -> 0 bytes .../install_scripts.cpython-38.pyc | Bin 2273 -> 0 bytes .../__pycache__/py36compat.cpython-38.pyc | Bin 4610 -> 0 bytes .../__pycache__/register.cpython-38.pyc | Bin 811 -> 0 bytes .../command/__pycache__/rotate.cpython-38.pyc | Bin 2520 -> 0 bytes .../__pycache__/saveopts.cpython-38.pyc | Bin 889 -> 0 bytes .../command/__pycache__/sdist.cpython-38.pyc | Bin 7859 -> 0 bytes .../command/__pycache__/setopt.cpython-38.pyc | Bin 4537 -> 0 bytes .../command/__pycache__/test.cpython-38.pyc | Bin 8475 -> 0 bytes .../command/__pycache__/upload.cpython-38.pyc | Bin 784 -> 0 bytes .../__pycache__/upload_docs.cpython-38.pyc | Bin 6140 -> 0 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 | 327 - .../setuptools/command/build_py.py | 270 - .../setuptools/command/develop.py | 221 - .../setuptools/command/dist_info.py | 36 - .../setuptools/command/easy_install.py | 2402 ------- .../setuptools/command/egg_info.py | 717 -- .../setuptools/command/install.py | 125 - .../setuptools/command/install_egg_info.py | 82 - .../setuptools/command/install_lib.py | 147 - .../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 | 252 - .../setuptools/command/setopt.py | 149 - .../site-packages/setuptools/command/test.py | 279 - .../setuptools/command/upload.py | 17 - .../setuptools/command/upload_docs.py | 206 - .../site-packages/setuptools/config.py | 659 -- .../site-packages/setuptools/dep_util.py | 23 - .../site-packages/setuptools/depends.py | 176 - .../site-packages/setuptools/dist.py | 1274 ---- .../site-packages/setuptools/errors.py | 16 - .../site-packages/setuptools/extension.py | 57 - .../setuptools/extern/__init__.py | 73 - .../__pycache__/__init__.cpython-38.pyc | Bin 2420 -> 0 bytes .../site-packages/setuptools/glob.py | 174 - .../site-packages/setuptools/installer.py | 150 - .../site-packages/setuptools/launch.py | 35 - .../site-packages/setuptools/lib2to3_ex.py | 62 - .../site-packages/setuptools/monkey.py | 179 - .../site-packages/setuptools/msvc.py | 1679 ----- .../site-packages/setuptools/namespaces.py | 107 - .../site-packages/setuptools/package_index.py | 1136 ---- .../site-packages/setuptools/py27compat.py | 60 - .../site-packages/setuptools/py31compat.py | 32 - .../site-packages/setuptools/py33compat.py | 59 - .../site-packages/setuptools/py34compat.py | 13 - .../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 | 44 - .../site-packages/setuptools/version.py | 6 - .../site-packages/setuptools/wheel.py | 220 - .../setuptools/windows_support.py | 29 - .../six-1.15.0.dist-info/INSTALLER | 1 - .../six-1.15.0.dist-info/LICENSE | 18 - .../six-1.15.0.dist-info/METADATA | 49 - .../site-packages/six-1.15.0.dist-info/RECORD | 8 - .../site-packages/six-1.15.0.dist-info/WHEEL | 6 - .../six-1.15.0.dist-info/top_level.txt | 1 - env/lib/python3.8/site-packages/six.py | 982 --- .../starlette-0.13.6.dist-info/INSTALLER | 1 - .../starlette-0.13.6.dist-info/LICENSE.md | 27 - .../starlette-0.13.6.dist-info/METADATA | 213 - .../starlette-0.13.6.dist-info/RECORD | 71 - .../starlette-0.13.6.dist-info/WHEEL | 5 - .../starlette-0.13.6.dist-info/top_level.txt | 2 - .../site-packages/starlette/__init__.py | 1 - .../__pycache__/__init__.cpython-38.pyc | Bin 213 -> 0 bytes .../__pycache__/applications.cpython-38.pyc | Bin 7951 -> 0 bytes .../__pycache__/authentication.cpython-38.pyc | Bin 5159 -> 0 bytes .../__pycache__/background.cpython-38.pyc | Bin 1709 -> 0 bytes .../__pycache__/concurrency.cpython-38.pyc | Bin 2077 -> 0 bytes .../__pycache__/config.cpython-38.pyc | Bin 3930 -> 0 bytes .../__pycache__/convertors.cpython-38.pyc | Bin 3348 -> 0 bytes .../__pycache__/datastructures.cpython-38.pyc | Bin 26364 -> 0 bytes .../__pycache__/endpoints.cpython-38.pyc | Bin 4517 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 3651 -> 0 bytes .../__pycache__/formparsers.cpython-38.pyc | Bin 6862 -> 0 bytes .../__pycache__/graphql.cpython-38.pyc | Bin 8691 -> 0 bytes .../__pycache__/requests.cpython-38.pyc | Bin 9453 -> 0 bytes .../__pycache__/responses.cpython-38.pyc | Bin 9704 -> 0 bytes .../__pycache__/routing.cpython-38.pyc | Bin 19966 -> 0 bytes .../__pycache__/schemas.cpython-38.pyc | Bin 4289 -> 0 bytes .../__pycache__/staticfiles.cpython-38.pyc | Bin 6357 -> 0 bytes .../__pycache__/status.cpython-38.pyc | Bin 2937 -> 0 bytes .../__pycache__/templating.cpython-38.pyc | Bin 3164 -> 0 bytes .../__pycache__/testclient.cpython-38.pyc | Bin 15491 -> 0 bytes .../__pycache__/types.cpython-38.pyc | Bin 403 -> 0 bytes .../__pycache__/websockets.cpython-38.pyc | Bin 5813 -> 0 bytes .../site-packages/starlette/applications.py | 200 - .../site-packages/starlette/authentication.py | 143 - .../site-packages/starlette/background.py | 35 - .../site-packages/starlette/concurrency.py | 56 - .../site-packages/starlette/config.py | 107 - .../site-packages/starlette/convertors.py | 81 - .../site-packages/starlette/datastructures.py | 675 -- .../site-packages/starlette/endpoints.py | 117 - .../site-packages/starlette/exceptions.py | 98 - .../site-packages/starlette/formparsers.py | 242 - .../site-packages/starlette/graphql.py | 278 - .../starlette/middleware/__init__.py | 17 - .../__pycache__/__init__.cpython-38.pyc | Bin 1221 -> 0 bytes .../__pycache__/authentication.cpython-38.pyc | Bin 1939 -> 0 bytes .../__pycache__/base.cpython-38.pyc | Bin 2686 -> 0 bytes .../__pycache__/cors.cpython-38.pyc | Bin 4573 -> 0 bytes .../__pycache__/errors.cpython-38.pyc | Bin 7244 -> 0 bytes .../__pycache__/gzip.cpython-38.pyc | Bin 3000 -> 0 bytes .../__pycache__/httpsredirect.cpython-38.pyc | Bin 1264 -> 0 bytes .../__pycache__/sessions.cpython-38.pyc | Bin 2537 -> 0 bytes .../__pycache__/trustedhost.cpython-38.pyc | Bin 1989 -> 0 bytes .../__pycache__/wsgi.cpython-38.pyc | Bin 4656 -> 0 bytes .../starlette/middleware/authentication.py | 52 - .../starlette/middleware/base.py | 67 - .../starlette/middleware/cors.py | 167 - .../starlette/middleware/errors.py | 246 - .../starlette/middleware/gzip.py | 97 - .../starlette/middleware/httpsredirect.py | 19 - .../starlette/middleware/sessions.py | 75 - .../starlette/middleware/trustedhost.py | 59 - .../starlette/middleware/wsgi.py | 143 - .../site-packages/starlette/py.typed | 0 .../site-packages/starlette/requests.py | 273 - .../site-packages/starlette/responses.py | 318 - .../site-packages/starlette/routing.py | 672 -- .../site-packages/starlette/schemas.py | 135 - .../site-packages/starlette/staticfiles.py | 219 - .../site-packages/starlette/status.py | 81 - .../site-packages/starlette/templating.py | 88 - .../site-packages/starlette/testclient.py | 491 -- .../site-packages/starlette/types.py | 9 - .../site-packages/starlette/websockets.py | 150 - .../toml-0.10.2.dist-info/INSTALLER | 1 - .../toml-0.10.2.dist-info/LICENSE | 27 - .../toml-0.10.2.dist-info/METADATA | 255 - .../toml-0.10.2.dist-info/RECORD | 16 - .../site-packages/toml-0.10.2.dist-info/WHEEL | 6 - .../toml-0.10.2.dist-info/top_level.txt | 1 - .../python3.8/site-packages/toml/__init__.py | 25 - .../toml/__pycache__/__init__.cpython-38.pyc | Bin 718 -> 0 bytes .../toml/__pycache__/decoder.cpython-38.pyc | Bin 23281 -> 0 bytes .../toml/__pycache__/encoder.cpython-38.pyc | Bin 9419 -> 0 bytes .../toml/__pycache__/ordered.cpython-38.pyc | Bin 911 -> 0 bytes .../toml/__pycache__/tz.cpython-38.pyc | Bin 1271 -> 0 bytes .../python3.8/site-packages/toml/decoder.py | 1057 --- .../python3.8/site-packages/toml/encoder.py | 304 - .../python3.8/site-packages/toml/ordered.py | 15 - env/lib/python3.8/site-packages/toml/tz.py | 24 - .../uvicorn-0.12.3.dist-info/INSTALLER | 1 - .../uvicorn-0.12.3.dist-info/LICENSE.md | 27 - .../uvicorn-0.12.3.dist-info/METADATA | 125 - .../uvicorn-0.12.3.dist-info/RECORD | 86 - .../uvicorn-0.12.3.dist-info/WHEEL | 5 - .../uvicorn-0.12.3.dist-info/entry_points.txt | 4 - .../uvicorn-0.12.3.dist-info/top_level.txt | 9 - .../site-packages/uvicorn/__init__.py | 5 - .../site-packages/uvicorn/__main__.py | 4 - .../__pycache__/__init__.cpython-38.pyc | Bin 376 -> 0 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 208 -> 0 bytes .../uvicorn/__pycache__/_types.cpython-38.pyc | Bin 1365 -> 0 bytes .../uvicorn/__pycache__/config.cpython-38.pyc | Bin 8671 -> 0 bytes .../__pycache__/importer.cpython-38.pyc | Bin 1164 -> 0 bytes .../__pycache__/logging.cpython-38.pyc | Bin 5690 -> 0 bytes .../uvicorn/__pycache__/main.cpython-38.pyc | Bin 7474 -> 0 bytes .../__pycache__/subprocess.cpython-38.pyc | Bin 1940 -> 0 bytes .../__pycache__/workers.cpython-38.pyc | Bin 2697 -> 0 bytes .../site-packages/uvicorn/_impl/__init__.py | 0 .../_impl/__pycache__/__init__.cpython-38.pyc | Bin 195 -> 0 bytes .../_impl/__pycache__/asyncio.cpython-38.pyc | Bin 6200 -> 0 bytes .../site-packages/uvicorn/_impl/asyncio.py | 256 - .../python3.8/site-packages/uvicorn/_types.py | 31 - .../python3.8/site-packages/uvicorn/config.py | 379 -- .../site-packages/uvicorn/importer.py | 37 - .../uvicorn/lifespan/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 198 -> 0 bytes .../lifespan/__pycache__/off.cpython-38.pyc | Bin 778 -> 0 bytes .../lifespan/__pycache__/on.cpython-38.pyc | Bin 3264 -> 0 bytes .../site-packages/uvicorn/lifespan/off.py | 12 - .../site-packages/uvicorn/lifespan/on.py | 97 - .../site-packages/uvicorn/logging.py | 132 - .../site-packages/uvicorn/loops/__init__.py | 0 .../loops/__pycache__/__init__.cpython-38.pyc | Bin 195 -> 0 bytes .../loops/__pycache__/asyncio.cpython-38.pyc | Bin 633 -> 0 bytes .../loops/__pycache__/auto.cpython-38.pyc | Bin 508 -> 0 bytes .../loops/__pycache__/uvloop.cpython-38.pyc | Bin 352 -> 0 bytes .../site-packages/uvicorn/loops/asyncio.py | 18 - .../site-packages/uvicorn/loops/auto.py | 11 - .../site-packages/uvicorn/loops/uvloop.py | 7 - .../python3.8/site-packages/uvicorn/main.py | 385 -- .../uvicorn/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 200 -> 0 bytes .../__pycache__/asgi2.cpython-38.pyc | Bin 680 -> 0 bytes .../__pycache__/debug.cpython-38.pyc | Bin 2748 -> 0 bytes .../__pycache__/message_logger.cpython-38.pyc | Bin 2508 -> 0 bytes .../__pycache__/proxy_headers.cpython-38.pyc | Bin 1839 -> 0 bytes .../__pycache__/wsgi.cpython-38.pyc | Bin 4294 -> 0 bytes .../site-packages/uvicorn/middleware/asgi2.py | 7 - .../site-packages/uvicorn/middleware/debug.py | 96 - .../uvicorn/middleware/message_logger.py | 68 - .../uvicorn/middleware/proxy_headers.py | 45 - .../site-packages/uvicorn/middleware/wsgi.py | 141 - .../uvicorn/protocols/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 199 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 1574 -> 0 bytes .../uvicorn/protocols/http/__init__.py | 0 .../http/__pycache__/__init__.cpython-38.pyc | Bin 204 -> 0 bytes .../http/__pycache__/auto.cpython-38.pyc | Bin 440 -> 0 bytes .../http/__pycache__/h11_impl.cpython-38.pyc | Bin 12876 -> 0 bytes .../__pycache__/httptools_impl.cpython-38.pyc | Bin 13959 -> 0 bytes .../uvicorn/protocols/http/auto.py | 10 - .../uvicorn/protocols/http/h11_impl.py | 535 -- .../uvicorn/protocols/http/httptools_impl.py | 563 -- .../site-packages/uvicorn/protocols/utils.py | 52 - .../uvicorn/protocols/websockets/__init__.py | 0 .../__pycache__/__init__.cpython-38.pyc | Bin 210 -> 0 bytes .../__pycache__/auto.cpython-38.pyc | Bin 524 -> 0 bytes .../websockets_impl.cpython-38.pyc | Bin 7777 -> 0 bytes .../__pycache__/wsproto_impl.cpython-38.pyc | Bin 9138 -> 0 bytes .../uvicorn/protocols/websockets/auto.py | 15 - .../protocols/websockets/websockets_impl.py | 251 - .../protocols/websockets/wsproto_impl.py | 306 - .../site-packages/uvicorn/subprocess.py | 61 - .../uvicorn/supervisors/__init__.py | 8 - .../__pycache__/__init__.cpython-38.pyc | Bin 494 -> 0 bytes .../__pycache__/basereload.cpython-38.pyc | Bin 2636 -> 0 bytes .../__pycache__/multiprocess.cpython-38.pyc | Bin 2132 -> 0 bytes .../__pycache__/statreload.cpython-38.pyc | Bin 1625 -> 0 bytes .../__pycache__/watchgodreload.cpython-38.pyc | Bin 2791 -> 0 bytes .../uvicorn/supervisors/basereload.py | 77 - .../uvicorn/supervisors/multiprocess.py | 63 - .../uvicorn/supervisors/statreload.py | 41 - .../uvicorn/supervisors/watchgodreload.py | 61 - .../site-packages/uvicorn/workers.py | 78 - .../wrapt-1.12.1.dist-info/INSTALLER | 1 - .../wrapt-1.12.1.dist-info/LICENSE | 24 - .../wrapt-1.12.1.dist-info/METADATA | 169 - .../wrapt-1.12.1.dist-info/RECORD | 15 - .../wrapt-1.12.1.dist-info/WHEEL | 5 - .../wrapt-1.12.1.dist-info/top_level.txt | 1 - .../python3.8/site-packages/wrapt/__init__.py | 16 - .../wrapt/__pycache__/__init__.cpython-38.pyc | Bin 999 -> 0 bytes .../__pycache__/decorators.cpython-38.pyc | Bin 9271 -> 0 bytes .../wrapt/__pycache__/importer.cpython-38.pyc | Bin 4279 -> 0 bytes .../wrapt/__pycache__/wrappers.cpython-38.pyc | Bin 24404 -> 0 bytes .../site-packages/wrapt/decorators.py | 516 -- .../python3.8/site-packages/wrapt/importer.py | 230 - .../python3.8/site-packages/wrapt/wrappers.py | 947 --- env/lib64 | 1 - env/pyvenv.cfg | 3 - .../CacheControl-0.12.6-py2.py3-none-any.whl | Bin 23290 -> 0 bytes .../appdirs-1.4.4-py2.py3-none-any.whl | Bin 14131 -> 0 bytes .../certifi-2020.4.5.1-py2.py3-none-any.whl | Bin 161630 -> 0 bytes .../chardet-3.0.4-py2.py3-none-any.whl | Bin 136755 -> 0 bytes .../colorama-0.4.3-py2.py3-none-any.whl | Bin 20362 -> 0 bytes .../contextlib2-0.6.0-py2.py3-none-any.whl | Bin 12457 -> 0 bytes .../distlib-0.3.0-py2.py3-none-any.whl | Bin 147296 -> 0 bytes .../distro-1.5.0-py2.py3-none-any.whl | Bin 19272 -> 0 bytes .../html5lib-1.0.1-py2.py3-none-any.whl | Bin 115285 -> 0 bytes .../idna-2.9-py2.py3-none-any.whl | Bin 62768 -> 0 bytes .../ipaddr-2.2.0-py2.py3-none-any.whl | Bin 19552 -> 0 bytes .../lockfile-0.12.2-py2.py3-none-any.whl | Bin 17238 -> 0 bytes .../msgpack-0.6.2-py2.py3-none-any.whl | Bin 88193 -> 0 bytes .../packaging-20.3-py2.py3-none-any.whl | Bin 37509 -> 0 bytes .../pep517-0.8.2-py2.py3-none-any.whl | Bin 21951 -> 0 bytes .../pip-20.1.1-py2.py3-none-any.whl | Bin 285469 -> 0 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 122578 -> 0 bytes .../progress-1.5-py2.py3-none-any.whl | Bin 12812 -> 0 bytes .../pyparsing-2.4.7-py2.py3-none-any.whl | Bin 72474 -> 0 bytes .../requests-2.23.0-py2.py3-none-any.whl | Bin 63192 -> 0 bytes .../resolvelib-0.3.0-py2.py3-none-any.whl | Bin 15663 -> 0 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 11621 -> 0 bytes .../setuptools-44.0.0-py2.py3-none-any.whl | Bin 472710 -> 0 bytes .../six-1.15.0-py2.py3-none-any.whl | Bin 15549 -> 0 bytes .../toml-0.10.1-py2.py3-none-any.whl | Bin 20955 -> 0 bytes .../urllib3-1.25.9-py2.py3-none-any.whl | Bin 123228 -> 0 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 15749 -> 0 bytes .../wheel-0.34.2-py2.py3-none-any.whl | Bin 30875 -> 0 bytes 1411 files changed, 182168 deletions(-) delete mode 100644 __pycache__/algorithm_management.cpython-38.pyc delete mode 100644 __pycache__/game_management.cpython-38.pyc delete mode 100644 __pycache__/main.cpython-38.pyc delete mode 100644 env/bin/Activate.ps1 delete mode 100644 env/bin/activate delete mode 100644 env/bin/activate.csh delete mode 100644 env/bin/activate.fish delete mode 100755 env/bin/autopep8 delete mode 100755 env/bin/easy_install delete mode 100755 env/bin/easy_install-3.8 delete mode 100755 env/bin/epylint delete mode 100755 env/bin/isort delete mode 100755 env/bin/pip delete mode 100755 env/bin/pip3 delete mode 100755 env/bin/pip3.8 delete mode 100755 env/bin/pycodestyle delete mode 100755 env/bin/pylint delete mode 100755 env/bin/pyreverse delete mode 120000 env/bin/python delete mode 120000 env/bin/python3 delete mode 120000 env/bin/python3.8 delete mode 100755 env/bin/symilar delete mode 100755 env/bin/uvicorn delete mode 100644 env/lib/python3.8/site-packages/__pycache__/autopep8.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/__pycache__/mccabe.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/__pycache__/pycodestyle.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/__pycache__/six.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING.LESSER delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/astroid/__init__.py delete mode 100644 env/lib/python3.8/site-packages/astroid/__pkginfo__.py delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/__pkginfo__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/_ast.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/arguments.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/as_string.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/bases.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/builder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/context.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/decorators.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/helpers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/inference.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/manager.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/mixins.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/modutils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/node_classes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/nodes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/objects.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/protocols.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/raw_building.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/rebuilder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/scoped_nodes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/test_utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/transforms.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/__pycache__/util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/_ast.py delete mode 100644 env/lib/python3.8/site-packages/astroid/arguments.py delete mode 100644 env/lib/python3.8/site-packages/astroid/as_string.py delete mode 100644 env/lib/python3.8/site-packages/astroid/bases.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_boto3.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_collections.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_crypt.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_curses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dataclasses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_functools.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_gi.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_http.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_io.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_nose.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_umath.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_ndarray.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_qt.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_random.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_re.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_responses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_scipy_signal.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_six.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_threading.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_typing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_argparse.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_attrs.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_boto3.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_builtin_inference.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_collections.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_crypt.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_curses.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_dataclasses.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_dateutil.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_fstrings.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_functools.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_gi.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_hashlib.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_http.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_io.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_mechanize.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_multiprocessing.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_namedtuple_enum.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_nose.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_function_base.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_multiarray.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numeric.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numerictypes.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_umath.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_ndarray.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_random_mtrand.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_numpy_utils.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_pkg_resources.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_pytest.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_qt.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_random.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_re.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_responses.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_scipy_signal.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_six.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_ssl.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_subprocess.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_threading.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_typing.py delete mode 100644 env/lib/python3.8/site-packages/astroid/brain/brain_uuid.py delete mode 100644 env/lib/python3.8/site-packages/astroid/builder.py delete mode 100644 env/lib/python3.8/site-packages/astroid/context.py delete mode 100644 env/lib/python3.8/site-packages/astroid/decorators.py delete mode 100644 env/lib/python3.8/site-packages/astroid/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/astroid/helpers.py delete mode 100644 env/lib/python3.8/site-packages/astroid/inference.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/__init__.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/__init__.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/spec.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/_import/util.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/dunder_lookup.py delete mode 100644 env/lib/python3.8/site-packages/astroid/interpreter/objectmodel.py delete mode 100644 env/lib/python3.8/site-packages/astroid/manager.py delete mode 100644 env/lib/python3.8/site-packages/astroid/mixins.py delete mode 100644 env/lib/python3.8/site-packages/astroid/modutils.py delete mode 100644 env/lib/python3.8/site-packages/astroid/node_classes.py delete mode 100644 env/lib/python3.8/site-packages/astroid/nodes.py delete mode 100644 env/lib/python3.8/site-packages/astroid/objects.py delete mode 100644 env/lib/python3.8/site-packages/astroid/protocols.py delete mode 100644 env/lib/python3.8/site-packages/astroid/raw_building.py delete mode 100644 env/lib/python3.8/site-packages/astroid/rebuilder.py delete mode 100644 env/lib/python3.8/site-packages/astroid/scoped_nodes.py delete mode 100644 env/lib/python3.8/site-packages/astroid/test_utils.py delete mode 100644 env/lib/python3.8/site-packages/astroid/transforms.py delete mode 100644 env/lib/python3.8/site-packages/astroid/util.py delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/PKG-INFO delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/SOURCES.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/dependency_links.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/installed-files.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/not-zip-safe delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/requires.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/autopep8.py delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/LICENSE.rst delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/click-7.1.2.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/click/__init__.py delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_bashcomplete.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_termui_impl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_textwrap.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_unicodefun.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/_winconsole.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/core.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/decorators.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/formatting.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/globals.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/parser.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/termui.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/testing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/types.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/click/_bashcomplete.py delete mode 100644 env/lib/python3.8/site-packages/click/_compat.py delete mode 100644 env/lib/python3.8/site-packages/click/_termui_impl.py delete mode 100644 env/lib/python3.8/site-packages/click/_textwrap.py delete mode 100644 env/lib/python3.8/site-packages/click/_unicodefun.py delete mode 100644 env/lib/python3.8/site-packages/click/_winconsole.py delete mode 100644 env/lib/python3.8/site-packages/click/core.py delete mode 100644 env/lib/python3.8/site-packages/click/decorators.py delete mode 100644 env/lib/python3.8/site-packages/click/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/click/formatting.py delete mode 100644 env/lib/python3.8/site-packages/click/globals.py delete mode 100644 env/lib/python3.8/site-packages/click/parser.py delete mode 100644 env/lib/python3.8/site-packages/click/termui.py delete mode 100644 env/lib/python3.8/site-packages/click/testing.py delete mode 100644 env/lib/python3.8/site-packages/click/types.py delete mode 100644 env/lib/python3.8/site-packages/click/utils.py delete mode 100644 env/lib/python3.8/site-packages/easy_install.py delete mode 100644 env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/fastapi/__init__.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/applications.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/background.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/concurrency.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/datastructures.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/encoders.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/exception_handlers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/logger.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/param_functions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/params.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/requests.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/responses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/routing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/staticfiles.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/templating.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/testclient.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/__pycache__/websockets.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/applications.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/background.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/concurrency.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/datastructures.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/__init__.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/models.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/models.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/dependencies/utils.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/encoders.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/exception_handlers.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/logger.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__init__.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/cors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/gzip.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/cors.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/gzip.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/httpsredirect.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/trustedhost.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/middleware/wsgi.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__init__.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/constants.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/docs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/models.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/constants.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/docs.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/models.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/openapi/utils.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/param_functions.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/params.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/py.typed delete mode 100644 env/lib/python3.8/site-packages/fastapi/requests.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/responses.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/routing.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__init__.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/api_key.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/http.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/oauth2.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/api_key.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/base.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/http.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/oauth2.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/open_id_connect_url.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/security/utils.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/staticfiles.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/templating.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/testclient.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/utils.py delete mode 100644 env/lib/python3.8/site-packages/fastapi/websockets.py delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/LICENSE.txt delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/h11-0.11.0.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/h11/__init__.py delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_abnf.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_connection.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_events.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_headers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_readers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_receivebuffer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_state.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/__pycache__/_writers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/_abnf.py delete mode 100644 env/lib/python3.8/site-packages/h11/_connection.py delete mode 100644 env/lib/python3.8/site-packages/h11/_events.py delete mode 100644 env/lib/python3.8/site-packages/h11/_headers.py delete mode 100644 env/lib/python3.8/site-packages/h11/_readers.py delete mode 100644 env/lib/python3.8/site-packages/h11/_receivebuffer.py delete mode 100644 env/lib/python3.8/site-packages/h11/_state.py delete mode 100644 env/lib/python3.8/site-packages/h11/_util.py delete mode 100644 env/lib/python3.8/site-packages/h11/_version.py delete mode 100644 env/lib/python3.8/site-packages/h11/_writers.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__init__.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/helpers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_against_stdlib_http.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_connection.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_events.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_headers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_helpers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_io.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_state.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/__pycache__/test_util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/h11/tests/data/test-file delete mode 100644 env/lib/python3.8/site-packages/h11/tests/helpers.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_against_stdlib_http.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_connection.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_events.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_headers.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_helpers.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_io.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_receivebuffer.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_state.py delete mode 100644 env/lib/python3.8/site-packages/h11/tests/test_util.py delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/isort-5.6.4.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/isort/__init__.py delete mode 100644 env/lib/python3.8/site-packages/isort/__main__.py delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/__main__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/_version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/api.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/comments.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/core.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/format.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/hooks.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/io.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/literal.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/logo.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/output.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/parse.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/place.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/profiles.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/pylama_isort.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/sections.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/settings.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/setuptools_commands.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/sorting.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/wrap.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/__pycache__/wrap_modes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_future/__init__.py delete mode 100644 env/lib/python3.8/site-packages/isort/_future/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_future/__pycache__/_dataclasses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_future/_dataclasses.py delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/LICENSE delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__init__.py delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/decoder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/encoder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/ordered.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/tz.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/decoder.py delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/encoder.py delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/ordered.py delete mode 100644 env/lib/python3.8/site-packages/isort/_vendored/toml/tz.py delete mode 100644 env/lib/python3.8/site-packages/isort/_version.py delete mode 100644 env/lib/python3.8/site-packages/isort/api.py delete mode 100644 env/lib/python3.8/site-packages/isort/comments.py delete mode 100644 env/lib/python3.8/site-packages/isort/core.py delete mode 100644 env/lib/python3.8/site-packages/isort/deprecated/__init__.py delete mode 100644 env/lib/python3.8/site-packages/isort/deprecated/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/deprecated/__pycache__/finders.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/deprecated/finders.py delete mode 100644 env/lib/python3.8/site-packages/isort/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/isort/format.py delete mode 100644 env/lib/python3.8/site-packages/isort/hooks.py delete mode 100644 env/lib/python3.8/site-packages/isort/io.py delete mode 100644 env/lib/python3.8/site-packages/isort/literal.py delete mode 100644 env/lib/python3.8/site-packages/isort/logo.py delete mode 100644 env/lib/python3.8/site-packages/isort/main.py delete mode 100644 env/lib/python3.8/site-packages/isort/output.py delete mode 100644 env/lib/python3.8/site-packages/isort/parse.py delete mode 100644 env/lib/python3.8/site-packages/isort/place.py delete mode 100644 env/lib/python3.8/site-packages/isort/profiles.py delete mode 100644 env/lib/python3.8/site-packages/isort/pylama_isort.py delete mode 100644 env/lib/python3.8/site-packages/isort/sections.py delete mode 100644 env/lib/python3.8/site-packages/isort/settings.py delete mode 100644 env/lib/python3.8/site-packages/isort/setuptools_commands.py delete mode 100644 env/lib/python3.8/site-packages/isort/sorting.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__init__.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/all.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py2.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py27.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py3.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py35.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py36.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py37.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py38.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py39.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/all.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py2.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py27.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py3.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py35.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py36.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py37.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py38.py delete mode 100644 env/lib/python3.8/site-packages/isort/stdlibs/py39.py delete mode 100644 env/lib/python3.8/site-packages/isort/utils.py delete mode 100644 env/lib/python3.8/site-packages/isort/wrap.py delete mode 100644 env/lib/python3.8/site-packages/isort/wrap_modes.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__init__.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/_version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/simple.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/slots.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/_version.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/compat.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/simple.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/slots.py delete mode 100644 env/lib/python3.8/site-packages/lazy_object_proxy/utils.py delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/metadata.json delete mode 100644 env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/mccabe.py delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/LICENSE.txt delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/pip-20.1.1.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/pip/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/__main__.py delete mode 100644 env/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/build_env.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cache.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/base_command.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/command_context.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/main.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/parser.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/progress_bars.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/req_command.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/spinners.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/cli/status_codes.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/cache.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/check.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/completion.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/configuration.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/debug.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/download.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/freeze.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/hash.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/help.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/install.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/list.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/search.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/show.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/commands/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/configuration.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/base.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/installed.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/collector.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/index/package_finder.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/locations.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/main.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/candidate.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/direct_url.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/format_control.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/index.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/link.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/scheme.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/search_scope.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/target_python.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/models/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/auth.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/cache.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/download.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/session.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/utils.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/network/xmlrpc.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel_legacy.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/check.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/freeze.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/editable_legacy.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/operations/prepare.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/pyproject.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/constructors.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/req_file.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/req_install.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/req_set.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/base.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/base.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/candidates.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/factory.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/provider.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/requirements.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/self_outdated_check.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/compat.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/compatibility_tags.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/direct_url_helpers.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/distutils_args.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/encoding.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/entrypoints.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/filetypes.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/glibc.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/hashes.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/inject_securetransport.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/logging.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/misc.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/models.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/packaging.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/pkg_resources.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/typing.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/unpacking.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/urls.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/utils/wheel.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/git.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py delete mode 100644 env/lib/python3.8/site-packages/pip/_internal/wheel_builder.py delete mode 100644 env/lib/python3.8/site-packages/pip/_vendor/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/appdirs.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/pyparsing.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/_vendor/six.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/extern/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pkg_resources/py31compat.py delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/namespace_packages.txt delete mode 100644 env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/pycodestyle.py delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/pydantic/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/class_validators.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/color.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/dataclasses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/datetime_parse.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/decorator.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/env_settings.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/error_wrappers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/errors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/fields.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/generics.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/json.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/mypy.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/networks.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/parse.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/schema.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/tools.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/types.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/typing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/validators.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/__pycache__/version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pydantic/class_validators.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/color.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/dataclasses.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/datetime_parse.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/decorator.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/env_settings.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/error_wrappers.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/errors.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/fields.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/generics.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/json.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/main.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/mypy.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/networks.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/parse.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/py.typed delete mode 100644 env/lib/python3.8/site-packages/pydantic/schema.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/tools.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/types.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/typing.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/utils.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/validators.py delete mode 100644 env/lib/python3.8/site-packages/pydantic/version.py delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/COPYING delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/pylint/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/__main__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/__pkginfo__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/__main__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/__pkginfo__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/constants.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/epylint.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/graph.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/interfaces.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/__pycache__/testutils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/async.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base_checker.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/classes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/format.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/imports.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/logging.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/misc.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/newstyle.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/python3.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/refactoring.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/similar.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/spelling.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/stdlib.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/strings.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/typecheck.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/__pycache__/variables.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/async.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/base.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/base_checker.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/classes.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/design_analysis.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/format.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/imports.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/logging.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/misc.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/newstyle.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/python3.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/raw_metrics.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/refactoring.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/similar.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/spelling.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/stdlib.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/strings.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/typecheck.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/utils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/checkers/variables.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/configuration_mixin.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/find_default_config_files.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/man_help_formatter.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/option.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/option_manager_mixin.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/option_parser.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/__pycache__/options_provider_mixin.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/config/configuration_mixin.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/find_default_config_files.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/man_help_formatter.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/option.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/option_manager_mixin.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/option_parser.py delete mode 100644 env/lib/python3.8/site-packages/pylint/config/options_provider_mixin.py delete mode 100644 env/lib/python3.8/site-packages/pylint/constants.py delete mode 100644 env/lib/python3.8/site-packages/pylint/epylint.py delete mode 100644 env/lib/python3.8/site-packages/pylint/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/check_docs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/check_elif.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/docparams.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/docstyle.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/emptystring.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/mccabe.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/_check_docs_utils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/bad_builtin.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/broad_try_clause.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/check_docs.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/check_elif.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/comparetozero.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/docparams.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/docstyle.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/emptystring.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/mccabe.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/overlapping_exceptions.py delete mode 100644 env/lib/python3.8/site-packages/pylint/extensions/redefined_variable_type.py delete mode 100644 env/lib/python3.8/site-packages/pylint/graph.py delete mode 100644 env/lib/python3.8/site-packages/pylint/interfaces.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/check_parallel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/pylinter.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/report_functions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/run.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/check_parallel.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/pylinter.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/report_functions.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/run.py delete mode 100644 env/lib/python3.8/site-packages/pylint/lint/utils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/message.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/message_definition.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/message_definition_store.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/message_handler_mix_in.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/__pycache__/message_id_store.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/message/message.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/message_definition.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/message_definition_store.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/message_handler_mix_in.py delete mode 100644 env/lib/python3.8/site-packages/pylint/message/message_id_store.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/__pycache__/writer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/diadefslib.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/diagrams.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/inspector.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/main.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/utils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/vcgutils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/pyreverse/writer.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/base_reporter.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/collecting_reporter.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/json_reporter.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/reports_handler_mix_in.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/__pycache__/text.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/base_reporter.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/collecting_reporter.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/json_reporter.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/reports_handler_mix_in.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/text.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/nodes.py delete mode 100644 env/lib/python3.8/site-packages/pylint/reporters/ureports/text_writer.py delete mode 100644 env/lib/python3.8/site-packages/pylint/testutils.py delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__init__.py delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__pycache__/ast_walker.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__pycache__/file_state.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__pycache__/pragma_parser.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/ast_walker.py delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/file_state.py delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/pragma_parser.py delete mode 100644 env/lib/python3.8/site-packages/pylint/utils/utils.py delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/LICENSE.txt delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/dependency_links.txt delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/zip-safe delete mode 100644 env/lib/python3.8/site-packages/setuptools/__init__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/_imp.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/archive_util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/build_meta.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/config.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/dep_util.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/depends.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/dist.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/errors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/extension.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/installer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/launch.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/monkey.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/msvc.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/namespaces.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/py27compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/py33compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/py34compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/sandbox.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/ssl_support.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/__pycache__/windows_support.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_deprecation_warning.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_imp.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/__init__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/six.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/ordered_set.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/tags.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/pyparsing.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/_vendor/six.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/archive_util.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/build_meta.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__init__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/alias.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/build_clib.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/build_py.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/develop.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/dist_info.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/easy_install.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/egg_info.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/install.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/install_lib.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/install_scripts.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/py36compat.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/register.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/saveopts.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/sdist.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/setopt.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/test.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/upload.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/__pycache__/upload_docs.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/alias.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/bdist_egg.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/bdist_rpm.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/build_clib.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/build_ext.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/build_py.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/develop.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/dist_info.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/easy_install.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/egg_info.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/install.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/install_egg_info.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/install_lib.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/install_scripts.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/launcher manifest.xml delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/py36compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/register.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/rotate.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/saveopts.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/sdist.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/setopt.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/test.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/upload.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/command/upload_docs.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/config.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/dep_util.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/depends.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/dist.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/errors.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/extension.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/extern/__init__.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/extern/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/setuptools/glob.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/installer.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/launch.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/lib2to3_ex.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/monkey.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/msvc.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/namespaces.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/package_index.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/py27compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/py31compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/py33compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/py34compat.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/sandbox.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/script (dev).tmpl delete mode 100644 env/lib/python3.8/site-packages/setuptools/script.tmpl delete mode 100644 env/lib/python3.8/site-packages/setuptools/site-patch.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/ssl_support.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/unicode_utils.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/version.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/wheel.py delete mode 100644 env/lib/python3.8/site-packages/setuptools/windows_support.py delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/six-1.15.0.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/six.py delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/LICENSE.md delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/starlette-0.13.6.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/starlette/__init__.py delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/applications.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/authentication.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/background.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/concurrency.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/config.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/convertors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/datastructures.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/endpoints.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/exceptions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/formparsers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/graphql.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/requests.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/responses.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/routing.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/schemas.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/staticfiles.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/status.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/templating.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/testclient.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/types.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/__pycache__/websockets.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/applications.py delete mode 100644 env/lib/python3.8/site-packages/starlette/authentication.py delete mode 100644 env/lib/python3.8/site-packages/starlette/background.py delete mode 100644 env/lib/python3.8/site-packages/starlette/concurrency.py delete mode 100644 env/lib/python3.8/site-packages/starlette/config.py delete mode 100644 env/lib/python3.8/site-packages/starlette/convertors.py delete mode 100644 env/lib/python3.8/site-packages/starlette/datastructures.py delete mode 100644 env/lib/python3.8/site-packages/starlette/endpoints.py delete mode 100644 env/lib/python3.8/site-packages/starlette/exceptions.py delete mode 100644 env/lib/python3.8/site-packages/starlette/formparsers.py delete mode 100644 env/lib/python3.8/site-packages/starlette/graphql.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__init__.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/authentication.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/base.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/cors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/errors.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/gzip.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/httpsredirect.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/sessions.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/trustedhost.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/__pycache__/wsgi.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/authentication.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/base.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/cors.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/errors.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/gzip.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/httpsredirect.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/sessions.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/trustedhost.py delete mode 100644 env/lib/python3.8/site-packages/starlette/middleware/wsgi.py delete mode 100644 env/lib/python3.8/site-packages/starlette/py.typed delete mode 100644 env/lib/python3.8/site-packages/starlette/requests.py delete mode 100644 env/lib/python3.8/site-packages/starlette/responses.py delete mode 100644 env/lib/python3.8/site-packages/starlette/routing.py delete mode 100644 env/lib/python3.8/site-packages/starlette/schemas.py delete mode 100644 env/lib/python3.8/site-packages/starlette/staticfiles.py delete mode 100644 env/lib/python3.8/site-packages/starlette/status.py delete mode 100644 env/lib/python3.8/site-packages/starlette/templating.py delete mode 100644 env/lib/python3.8/site-packages/starlette/testclient.py delete mode 100644 env/lib/python3.8/site-packages/starlette/types.py delete mode 100644 env/lib/python3.8/site-packages/starlette/websockets.py delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/toml-0.10.2.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/toml/__init__.py delete mode 100644 env/lib/python3.8/site-packages/toml/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/toml/__pycache__/decoder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/toml/__pycache__/encoder.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/toml/__pycache__/ordered.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/toml/__pycache__/tz.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/toml/decoder.py delete mode 100644 env/lib/python3.8/site-packages/toml/encoder.py delete mode 100644 env/lib/python3.8/site-packages/toml/ordered.py delete mode 100644 env/lib/python3.8/site-packages/toml/tz.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/LICENSE.md delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/entry_points.txt delete mode 100644 env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__main__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/__main__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/_types.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/config.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/importer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/logging.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/main.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/subprocess.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/__pycache__/workers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/_impl/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/asyncio.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/_types.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/config.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/importer.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/off.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/on.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/off.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/lifespan/on.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/logging.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/asyncio.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/auto.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/uvloop.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/asyncio.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/auto.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/loops/uvloop.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/main.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/asgi2.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/debug.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/message_logger.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/proxy_headers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/wsgi.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/asgi2.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/debug.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/middleware/wsgi.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/utils.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/auto.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/h11_impl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/httptools_impl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/auto.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/utils.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/auto.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/websockets_impl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/auto.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/protocols/websockets/wsproto_impl.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/subprocess.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__init__.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/basereload.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/multiprocess.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/statreload.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/watchgodreload.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/basereload.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/multiprocess.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/statreload.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/supervisors/watchgodreload.py delete mode 100644 env/lib/python3.8/site-packages/uvicorn/workers.py delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL delete mode 100644 env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt delete mode 100644 env/lib/python3.8/site-packages/wrapt/__init__.py delete mode 100644 env/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/wrapt/__pycache__/importer.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc delete mode 100644 env/lib/python3.8/site-packages/wrapt/decorators.py delete mode 100644 env/lib/python3.8/site-packages/wrapt/importer.py delete mode 100644 env/lib/python3.8/site-packages/wrapt/wrappers.py delete mode 120000 env/lib64 delete mode 100644 env/pyvenv.cfg delete mode 100644 env/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/colorama-0.4.3-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/distro-1.5.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/idna-2.9-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/msgpack-0.6.2-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/packaging-20.3-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/pkg_resources-0.0.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/progress-1.5-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/requests-2.23.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/six-1.15.0-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/urllib3-1.25.9-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl delete mode 100644 env/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl diff --git a/__pycache__/algorithm_management.cpython-38.pyc b/__pycache__/algorithm_management.cpython-38.pyc deleted file mode 100644 index 2d9ef70d4acf92a173b861c75d591a67c33f0338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1932 zcmah~&2Aev5GHq5D{1{BB~BANzf4mU)y2N2f)Tex3j?iMBrpo>WkD}#d6Ql4mdlMJ zp*Q>LYfriKRQTQ}=u;HD_S9D>P_#3YWvh0PP#|~6;mmw9{7CJstV9Ib&p-W^{L&)i z51cHvHcXyDuYZR@5J7WN(3nz`z1%DO*e`-OaC1Lz6=56}?YK>eq{k%gd__bcS|>!b zWO(eyUD)uk zFK(O$;-*+TA)sFceNXh9=9c*26g-IAZ>hK=)=vV^_d$Q-T)*M;OAz-iM7SsJyB#;h z(hD+p_$OpX2Gn+UzT16XHb&}!XFK0kCMy-sZSZwg8(8Un#%uXaDP(S2W>U#IMZ3l3 z!{izC`Y8;O#8i;j+r!)fL5H)icmDO^+j<#-Cb*DVLn1;z)V3=-`MA`XIV^V7L1_cU z3u%L#tFaAhnQCclB;UxiF?>GTLLlNz`Uqs#d zw6&F~%-HUQ@$}1GSg09iN*=K>U}Q&-9+NOg4a=`od8F9IepcdQS{79Sw+-hx>YKn_X=qfP8@rohr63S>5axnK4p;&!_)yIBfFk-q8Cn&$chmkL_oQ>k0c< zbFDvR1%D-(e8Vw!R+O&+y@DV@%=ej+2@WR@d>n3pr>l6~979w&&lD6!%v@kOGw_K# zYTzj60q5&(<9k7jrIMOs-siC22WPkiWf%lDFnnCwRW0iZI46;xaF^P3QxuTBT@rAm zbmp$z=*){dP;$rSxDA|1V3vA7wRuAs`{&T>Wf%BI@Dq@1T1>=u_{Xz>DD9hyE`J(&3%} diff --git a/__pycache__/game_management.cpython-38.pyc b/__pycache__/game_management.cpython-38.pyc deleted file mode 100644 index eaffa90f1cd0402d6ca328849284167b4453c0ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1120 zcmYjQyKWRQ6t(BIGn0MsND)La?Ka5|M34Ydv=WIBu#FpQ7<*TSd0~4ZZQ7)zrQ!#| zXYdJ#$}JVYKm*sFJjT+!KF8PBzCN~BlSzu8{rvia{_+s|ZOO1jK#sta2FDP?C8{vN z*kZ5rDxdfc`(;ptB&;G5IUbawDkd>T9A6@moFEpm=nAoj`eK3fH103DN zM>l;uh$RD@4)D$Zj{%SRUERJD$3c@llgloR>`@^p>QK_DMbN6VeZ*s6TC8N_>Zs_8u1H zmT?!~btwQvUyabBsTGN}C^@b2_G}TGn9@40IHe|~v}#xfA!^2ye(v(Jk4XF0%#6~! zt{a`ZMJSb_9ra;p834LQatfVue;@B3Z0w>{UgsNLff)PkR*oQ^fT^e8QXJzknDzI) z#dGXtUW5k~$V&pd(#7)=uCsNgJIS+Kjk0wkvs-<$<7Kv%O_dd$l(1oD(=sJ==L%l< zW-7UYn^91feV!)J`9_(M>Z&T2+iQ590*FD-X7J>bn}^!~Pzh+0xZRaJ{T!FY@OP=Gglec>e+Dbro*_ diff --git a/__pycache__/main.cpython-38.pyc b/__pycache__/main.cpython-38.pyc deleted file mode 100644 index 3c070e77b0537f7e238f0cb84a50bc453778fcf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 422 zcmYk2%}N6?5XY0V{*+I`)q^l6H#zRx4t5$nBs<6E;(;GFo6wa zZ^IFB%o%bOs-B8e{2a;zlh+h`Z%P}SeAZKKbG+(xq#ZA-(C{Nu3UO_t5F40 zzd#FxAYpZUZsw)aeqn_I4-ZhIfI Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - -For more information on Execution Policies: -https://go.microsoft.com/fwlink/?LinkID=135170 - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0, 1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} -else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} -else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/env/bin/activate b/env/bin/activate deleted file mode 100644 index 2263cb00..00000000 --- a/env/bin/activate +++ /dev/null @@ -1,76 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r - fi - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - if [ ! "${1:-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="/home/secretone/git_repos/uni/pactheman-server/env" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/bin:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - if [ "x(env) " != x ] ; then - PS1="(env) ${PS1:-}" - else - if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then - # special case for Aspen magic directories - # see https://aspen.io/ - PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" - else - PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" - fi - fi - export PS1 -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r -fi diff --git a/env/bin/activate.csh b/env/bin/activate.csh deleted file mode 100644 index 4464ef14..00000000 --- a/env/bin/activate.csh +++ /dev/null @@ -1,37 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi . -# 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 "/home/secretone/git_repos/uni/pactheman-server/env" - -set _OLD_VIRTUAL_PATH="$PATH" -setenv PATH "$VIRTUAL_ENV/bin:$PATH" - - -set _OLD_VIRTUAL_PROMPT="$prompt" - -if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then - if ("env" != "") then - set env_name = "env" - else - if (`basename "VIRTUAL_ENV"` == "__") then - # special case for Aspen magic directories - # see https://aspen.io/ - 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/env/bin/activate.fish b/env/bin/activate.fish deleted file mode 100644 index 1845a655..00000000 --- a/env/bin/activate.fish +++ /dev/null @@ -1,75 +0,0 @@ -# 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 "/home/secretone/git_repos/uni/pactheman-server/env" - -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 "(env) " - printf "%s%s" "(env) " (set_color normal) - else - # ...Otherwise, prepend env - set -l _checkbase (basename "$VIRTUAL_ENV") - if test $_checkbase = "__" - # special case for Aspen magic directories - # see https://aspen.io/ - 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/env/bin/autopep8 b/env/bin/autopep8 deleted file mode 100755 index 38f30b36..00000000 --- a/env/bin/autopep8 +++ /dev/null @@ -1,12 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'autopep8==1.5.4','console_scripts','autopep8' -__requires__ = 'autopep8==1.5.4' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('autopep8==1.5.4', 'console_scripts', 'autopep8')() - ) diff --git a/env/bin/easy_install b/env/bin/easy_install deleted file mode 100755 index 19981fc1..00000000 --- a/env/bin/easy_install +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- 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/env/bin/easy_install-3.8 b/env/bin/easy_install-3.8 deleted file mode 100755 index 19981fc1..00000000 --- a/env/bin/easy_install-3.8 +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- 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/env/bin/epylint b/env/bin/epylint deleted file mode 100755 index d69e4fc9..00000000 --- a/env/bin/epylint +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- 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/env/bin/isort b/env/bin/isort deleted file mode 100755 index 26fd19a0..00000000 --- a/env/bin/isort +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- 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/env/bin/pip b/env/bin/pip deleted file mode 100755 index 241f91f5..00000000 --- a/env/bin/pip +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/env/bin/pip3 b/env/bin/pip3 deleted file mode 100755 index 241f91f5..00000000 --- a/env/bin/pip3 +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/env/bin/pip3.8 b/env/bin/pip3.8 deleted file mode 100755 index 241f91f5..00000000 --- a/env/bin/pip3.8 +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- coding: utf-8 -*- -import re -import sys -from pip._internal.cli.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/env/bin/pycodestyle b/env/bin/pycodestyle deleted file mode 100755 index 228da631..00000000 --- a/env/bin/pycodestyle +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- coding: utf-8 -*- -import re -import sys -from pycodestyle import _main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(_main()) diff --git a/env/bin/pylint b/env/bin/pylint deleted file mode 100755 index c3842ed8..00000000 --- a/env/bin/pylint +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- 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/env/bin/pyreverse b/env/bin/pyreverse deleted file mode 100755 index 6a3081b9..00000000 --- a/env/bin/pyreverse +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- 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/env/bin/python b/env/bin/python deleted file mode 120000 index 4e58b606..00000000 --- a/env/bin/python +++ /dev/null @@ -1 +0,0 @@ -python3.8 \ No newline at end of file diff --git a/env/bin/python3 b/env/bin/python3 deleted file mode 120000 index 4e58b606..00000000 --- a/env/bin/python3 +++ /dev/null @@ -1 +0,0 @@ -python3.8 \ No newline at end of file diff --git a/env/bin/python3.8 b/env/bin/python3.8 deleted file mode 120000 index 02a13896..00000000 --- a/env/bin/python3.8 +++ /dev/null @@ -1 +0,0 @@ -/usr/bin/python3.8 \ No newline at end of file diff --git a/env/bin/symilar b/env/bin/symilar deleted file mode 100755 index db834b13..00000000 --- a/env/bin/symilar +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python -# -*- 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/env/bin/uvicorn b/env/bin/uvicorn deleted file mode 100755 index dbb0a531..00000000 --- a/env/bin/uvicorn +++ /dev/null @@ -1,8 +0,0 @@ -#!/home/secretone/git_repos/uni/pactheman-server/env/bin/python3.8 -# -*- coding: utf-8 -*- -import re -import sys -from uvicorn.main import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/env/lib/python3.8/site-packages/__pycache__/autopep8.cpython-38.pyc b/env/lib/python3.8/site-packages/__pycache__/autopep8.cpython-38.pyc deleted file mode 100644 index 64f02305c71ed9d04e4e29dcaf154c69435b6354..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101119 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%0Avchqsu_%vn?RwnaB4BEO*Py!)pcWRgN3T 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 Y{jbA%$}gYu9bldB`)i&Q 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 XJ@fR;9~$|Y#o|63IPWbUDVqNWxp$=} diff --git a/env/lib/python3.8/site-packages/__pycache__/pycodestyle.cpython-38.pyc b/env/lib/python3.8/site-packages/__pycache__/pycodestyle.cpython-38.pyc deleted file mode 100644 index f446c977fc6708c897356befdf4e52ac0f8f4bdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72651 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

B0d6<+=T|Pm!u= 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 diff --git a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING deleted file mode 100644 index d511905c..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -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 give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 Program -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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), 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 Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. 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 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/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING.LESSER b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING.LESSER deleted file mode 100644 index 2d2d780e..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/COPYING.LESSER +++ /dev/null @@ -1,510 +0,0 @@ - - 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/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/INSTALLER b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/METADATA b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/METADATA deleted file mode 100644 index 47dad942..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/METADATA +++ /dev/null @@ -1,118 +0,0 @@ -Metadata-Version: 2.1 -Name: astroid -Version: 2.4.2 -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.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=3.5 -Requires-Dist: lazy-object-proxy (==1.4.*) -Requires-Dist: six (~=1.12) -Requires-Dist: wrapt (~=1.11) -Requires-Dist: typed-ast (<1.5,>=1.4.0) ; implementation_name == "cpython" and python_version < "3.8" - -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 - -.. |tideliftlogo| image:: doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png - :width: 75 - :height: 60 - :alt: Tidelift - -.. list-table:: - :widths: 10 100 - - * - |tideliftlogo| - - Professional support for astroid is available as part of the `Tidelift - Subscription`_. Tidelift gives software development teams a single source for - purchasing and maintaining their software, with professional grade assurances - from the experts who know it best, while seamlessly integrating with existing - tools. - -.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-astroid?utm_source=pypi-astroid&utm_medium=referral&utm_campaign=readme - - - -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/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/RECORD b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/RECORD deleted file mode 100644 index 74774657..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/RECORD +++ /dev/null @@ -1,151 +0,0 @@ -astroid-2.4.2.dist-info/COPYING,sha256=qxX9UmvY3Rip5368E5ZWv00z6X_HI4zRG_YOK5uGZsY,17987 -astroid-2.4.2.dist-info/COPYING.LESSER,sha256=qb3eVhbs3R6YC0TzYGAO6Hg7H5m4zIOivrFjoKOQ6GE,26527 -astroid-2.4.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -astroid-2.4.2.dist-info/METADATA,sha256=mWlOM8vl6thD_vA7Lzn2yKmQuaX8NukwS72gEpsGM0U,3915 -astroid-2.4.2.dist-info/RECORD,, -astroid-2.4.2.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92 -astroid-2.4.2.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8 -astroid/__init__.py,sha256=zZF5EWBTfOtOcFd62WMbhLAtS2b_Fm-3JJW2AVUUMUI,5655 -astroid/__pkginfo__.py,sha256=G6QlkatrWucF445cQW7Kb2ZSgBzf7TiKLPwqkP0CoQU,2329 -astroid/__pycache__/__init__.cpython-38.pyc,, -astroid/__pycache__/__pkginfo__.cpython-38.pyc,, -astroid/__pycache__/_ast.cpython-38.pyc,, -astroid/__pycache__/arguments.cpython-38.pyc,, -astroid/__pycache__/as_string.cpython-38.pyc,, -astroid/__pycache__/bases.cpython-38.pyc,, -astroid/__pycache__/builder.cpython-38.pyc,, -astroid/__pycache__/context.cpython-38.pyc,, -astroid/__pycache__/decorators.cpython-38.pyc,, -astroid/__pycache__/exceptions.cpython-38.pyc,, -astroid/__pycache__/helpers.cpython-38.pyc,, -astroid/__pycache__/inference.cpython-38.pyc,, -astroid/__pycache__/manager.cpython-38.pyc,, -astroid/__pycache__/mixins.cpython-38.pyc,, -astroid/__pycache__/modutils.cpython-38.pyc,, -astroid/__pycache__/node_classes.cpython-38.pyc,, -astroid/__pycache__/nodes.cpython-38.pyc,, -astroid/__pycache__/objects.cpython-38.pyc,, -astroid/__pycache__/protocols.cpython-38.pyc,, -astroid/__pycache__/raw_building.cpython-38.pyc,, -astroid/__pycache__/rebuilder.cpython-38.pyc,, -astroid/__pycache__/scoped_nodes.cpython-38.pyc,, -astroid/__pycache__/test_utils.cpython-38.pyc,, -astroid/__pycache__/transforms.cpython-38.pyc,, -astroid/__pycache__/util.cpython-38.pyc,, -astroid/_ast.py,sha256=n1U2HblBNrMhsmrjF84HUfIgEZ3PyHyiJJOrOkgiUFk,3385 -astroid/arguments.py,sha256=KJcZn7HeEhj2fZICr-9Pi7iueCNDZRQWh0T7O-qb-AE,12558 -astroid/as_string.py,sha256=8bOZWsGG79TLmlzRzPtmHdanIAqQUFTKiYH873iMhOw,22821 -astroid/bases.py,sha256=wL9C23mHFaj7vhMqM83DdsU6kfP488aEjoFWaO8p6Cg,19175 -astroid/brain/__pycache__/brain_argparse.cpython-38.pyc,, -astroid/brain/__pycache__/brain_attrs.cpython-38.pyc,, -astroid/brain/__pycache__/brain_boto3.cpython-38.pyc,, -astroid/brain/__pycache__/brain_builtin_inference.cpython-38.pyc,, -astroid/brain/__pycache__/brain_collections.cpython-38.pyc,, -astroid/brain/__pycache__/brain_crypt.cpython-38.pyc,, -astroid/brain/__pycache__/brain_curses.cpython-38.pyc,, -astroid/brain/__pycache__/brain_dataclasses.cpython-38.pyc,, -astroid/brain/__pycache__/brain_dateutil.cpython-38.pyc,, -astroid/brain/__pycache__/brain_fstrings.cpython-38.pyc,, -astroid/brain/__pycache__/brain_functools.cpython-38.pyc,, -astroid/brain/__pycache__/brain_gi.cpython-38.pyc,, -astroid/brain/__pycache__/brain_hashlib.cpython-38.pyc,, -astroid/brain/__pycache__/brain_http.cpython-38.pyc,, -astroid/brain/__pycache__/brain_io.cpython-38.pyc,, -astroid/brain/__pycache__/brain_mechanize.cpython-38.pyc,, -astroid/brain/__pycache__/brain_multiprocessing.cpython-38.pyc,, -astroid/brain/__pycache__/brain_namedtuple_enum.cpython-38.pyc,, -astroid/brain/__pycache__/brain_nose.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_core_umath.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_ndarray.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-38.pyc,, -astroid/brain/__pycache__/brain_numpy_utils.cpython-38.pyc,, -astroid/brain/__pycache__/brain_pkg_resources.cpython-38.pyc,, -astroid/brain/__pycache__/brain_pytest.cpython-38.pyc,, -astroid/brain/__pycache__/brain_qt.cpython-38.pyc,, -astroid/brain/__pycache__/brain_random.cpython-38.pyc,, -astroid/brain/__pycache__/brain_re.cpython-38.pyc,, -astroid/brain/__pycache__/brain_responses.cpython-38.pyc,, -astroid/brain/__pycache__/brain_scipy_signal.cpython-38.pyc,, -astroid/brain/__pycache__/brain_six.cpython-38.pyc,, -astroid/brain/__pycache__/brain_ssl.cpython-38.pyc,, -astroid/brain/__pycache__/brain_subprocess.cpython-38.pyc,, -astroid/brain/__pycache__/brain_threading.cpython-38.pyc,, -astroid/brain/__pycache__/brain_typing.cpython-38.pyc,, -astroid/brain/__pycache__/brain_uuid.cpython-38.pyc,, -astroid/brain/brain_argparse.py,sha256=5XqcThekktCIWRlWAMs-R47wkbsOUSnQlsEbLEnRpsY,1041 -astroid/brain/brain_attrs.py,sha256=k8zJqIXsIbQrncthrzyB5NtdPTktgVi9wG7nyl8xMzs,2208 -astroid/brain/brain_boto3.py,sha256=nE8Cw_S_Gp___IszRDRkhEGS6WGrKcF_gTOs3GVxH9k,862 -astroid/brain/brain_builtin_inference.py,sha256=F6_09yM2mmu_u3ad_f9Uumc-q0lDA2CY8v9-PYtUMmA,28793 -astroid/brain/brain_collections.py,sha256=Uqi4VmpLDl0ndQa9x-5tIXRtVdtI6TlwR9KNHmOqLyw,2724 -astroid/brain/brain_crypt.py,sha256=gA7Q4GVuAM4viuTGWM6SNTPQXv5Gr_mFapyKMTRcsJ0,875 -astroid/brain/brain_curses.py,sha256=tDnlCP1bEvleqCMz856yua9mM5um1p_JendFhT4rBFk,3303 -astroid/brain/brain_dataclasses.py,sha256=5WndOYSY0oi2v-Od6KdPte-FKt00LoNRH2riSB4S1os,1647 -astroid/brain/brain_dateutil.py,sha256=GwDrgbaUkKbp3ImLAvuUtPuDBeK3lPh0bNI_Wphm2_8,801 -astroid/brain/brain_fstrings.py,sha256=Jaf-G-wkLecwG4jfjjfR8MDKzgAjjn2mgrrWZQLOAd8,2126 -astroid/brain/brain_functools.py,sha256=Nljy7o2vu16S2amFot4wdTI0U76Yafq-ujVPHOdGgCE,5481 -astroid/brain/brain_gi.py,sha256=oraXhBWyCCxmPEAEvRboeTIho0--ORObvckni00_1wY,7554 -astroid/brain/brain_hashlib.py,sha256=W2cS6-rixdBcre6lPWIuSOqPLCcVji5JBlImdPbV6Qo,2292 -astroid/brain/brain_http.py,sha256=a_8eIACvZetnR2xI4ZARVMuB1WSjyyqM3rCl2DVltMo,10524 -astroid/brain/brain_io.py,sha256=wEY3vvTeV23tYxFn8HHQeyjhb7-jqzwgwNI-kl2Yu-c,1476 -astroid/brain/brain_mechanize.py,sha256=boZxoCxPGSpHC_RccO5U026hyXyhunXR55M9WM1lYTo,895 -astroid/brain/brain_multiprocessing.py,sha256=9OswtRuVBj-KemJ0yp4prz8mrkJDzOzN6n13u2MgmwM,3096 -astroid/brain/brain_namedtuple_enum.py,sha256=eZ8IaHPLLHBakywJ3q4Ogtd2Tk0gtNcAgYAloMAKTjM,15966 -astroid/brain/brain_nose.py,sha256=PSPmme611h7fC8MKuVXbiGw0HZhdmIuoxM6yieZ1OOc,2217 -astroid/brain/brain_numpy_core_fromnumeric.py,sha256=NxiHbcMyQQ3Gpx4KEA5eAmGrpjlPN5rfXjRLjHPOVkw,621 -astroid/brain/brain_numpy_core_function_base.py,sha256=7i6Kge_PviqoWXhbeRgB581xwLo0dxvO54_5UB3ppig,1168 -astroid/brain/brain_numpy_core_multiarray.py,sha256=vr-nBt3EF_z-UmHmcAlJhGorgDXPpQaYX8g4TWu_2Vw,4015 -astroid/brain/brain_numpy_core_numeric.py,sha256=M0RXOym2YC-DaZfRqGNIpr6s-Oh1KHn1okGr3PtPl0k,1384 -astroid/brain/brain_numpy_core_numerictypes.py,sha256=ltlZyQprEbVdUJpC_ERGyXyJsYwzFHx7zGYDLheIonA,8013 -astroid/brain/brain_numpy_core_umath.py,sha256=je6K3ILMen2mgkZseHCOjOgnFV6SaNgAihEi6irhbRk,4436 -astroid/brain/brain_numpy_ndarray.py,sha256=WZbRG7GgOWZ68sEr4JjZUnJHLfUc91xp2mucHeLMrnw,8463 -astroid/brain/brain_numpy_random_mtrand.py,sha256=WRy_CStllgZN2B3Dw2qxXbY4SBrCzu-cdaK230VQHaE,3278 -astroid/brain/brain_numpy_utils.py,sha256=ZYtCVmn1x6P7iwYFohdW3CCrvVT5BCNYe-7jKcz_25s,1875 -astroid/brain/brain_pkg_resources.py,sha256=S_5UED1Zg8ObEJumRdpYGnjxZzemh_G_NFj3p5NGPfc,2262 -astroid/brain/brain_pytest.py,sha256=RYp7StKnC22n4vFJkHH5h7DAFWtouIcg-ZCXQ8Oz3xk,2390 -astroid/brain/brain_qt.py,sha256=m2s4YXFrnOynWDf9omHOBLVqFriBdGJAmvarJCxiffM,2536 -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_responses.py,sha256=GIAGkwMEGEZ9bJHI9uBGs_UmUy3DRBtjI_j_8dLBVsc,1534 -astroid/brain/brain_scipy_signal.py,sha256=IKNnGXzEH5FKhPHM2hv57pNdo1emThWwZ0ksckdsOeE,2255 -astroid/brain/brain_six.py,sha256=79aws4au6ZQJuf-YhBT4R-9wuVOwg-u0T42aUhCswK0,6187 -astroid/brain/brain_ssl.py,sha256=9dMCTQ0JsX2gpdmBkYO7BByw3zN23oXRL8Svo2S1V28,3722 -astroid/brain/brain_subprocess.py,sha256=yp-HsE69uh7T7C1kZYciAdRMQ48aNT51lI032oDppDk,4688 -astroid/brain/brain_threading.py,sha256=dY8YwZ-zrB30_CQFYWh4AK3qUVssakgwLVwunQ6yYkU,837 -astroid/brain/brain_typing.py,sha256=iFw33beNCitCJjJNvccIY6SsFJcdKVDdl-56DxDioh0,2780 -astroid/brain/brain_uuid.py,sha256=YzfiOXavu515cS1prsKGfY4-12g_KWT0Yr4-5ti0v74,569 -astroid/builder.py,sha256=72JlHrXRF9sS5zh1mqXlRHGFg88Efc2rm9yRJKDIShA,16891 -astroid/context.py,sha256=MpwiEzWZ39a4WyqYgbSmePL2nZLqALt1gjrvi3TP35U,5169 -astroid/decorators.py,sha256=z_wTjsiMlu_ElHtYUUuxaB2F_s4G0Ks7bmtCZS3IQ_Q,4283 -astroid/exceptions.py,sha256=GLiZo9BdWILJShO-il8ra-tPZqaODMAX987F--LWv2w,6891 -astroid/helpers.py,sha256=3YoJeVLoS-66T_abDorUNHiP8m2R7-faNnpc5yPJhrc,9448 -astroid/inference.py,sha256=UiKKPRYqb5JINQIw1lSdBniHhXjCohCGAqycp2GkVI4,34686 -astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -astroid/interpreter/__pycache__/__init__.cpython-38.pyc,, -astroid/interpreter/__pycache__/dunder_lookup.cpython-38.pyc,, -astroid/interpreter/__pycache__/objectmodel.cpython-38.pyc,, -astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -astroid/interpreter/_import/__pycache__/__init__.cpython-38.pyc,, -astroid/interpreter/_import/__pycache__/spec.cpython-38.pyc,, -astroid/interpreter/_import/__pycache__/util.cpython-38.pyc,, -astroid/interpreter/_import/spec.py,sha256=rZ9kX3I0xPo_pFAYWeOk2Xbi4ZIg_5bRsouZgxOXegA,11436 -astroid/interpreter/_import/util.py,sha256=inubUz6F3_kaMFaeleKUW6E6wCMIPrhU882zvwEZ02I,255 -astroid/interpreter/dunder_lookup.py,sha256=dP-AZU_aGPNt03b1ttrMglxzeU3NtgnG0MfpSLPH6sg,2155 -astroid/interpreter/objectmodel.py,sha256=bbPIaamrqrx7WHtG5YNs9dbrlDC00GrJPxPGoSTsnqg,25792 -astroid/manager.py,sha256=jmEm9uH00mPA2Y68s10xrPNbZaadv_2c-CWluB3SYoE,13701 -astroid/mixins.py,sha256=F2rv2Ow7AU3YT_2jitVJik95ZWRVK6hpf8BrkkspzUY,5571 -astroid/modutils.py,sha256=GBW5Z691eqf6VAnPsZzeQ0WYzrl-0GGTHkkZNb_9XRQ,23242 -astroid/node_classes.py,sha256=cBRkZ_u8ZoRkiXznYWq1L3I7cO-P9nGowNCy8T7Qpzk,142740 -astroid/nodes.py,sha256=WoyRe22GNVRc2TRHWOUlqdxCdOVD8GKOq9v1LpPhkr8,2978 -astroid/objects.py,sha256=caKeQPBtrrfqa1q844vkehXwpdMzvph5YJdJJdbD_m8,11035 -astroid/protocols.py,sha256=m1ZHvKvFQZSZp993na4f9s8V17kqNPRfH-XpQc8gJ7c,27396 -astroid/raw_building.py,sha256=PI70y2mPQ7JURDVyNZ6deeBFkvjNNaOQBkuo0VPbvQ4,17340 -astroid/rebuilder.py,sha256=xn82eWlxzGcDd2VACUnNNWCxArfV9HI8g67fUip0XFk,39411 -astroid/scoped_nodes.py,sha256=fUrmTyltaLCr9-i8RdC2e5dPA9O8w946Mvvft8mgXdM,98203 -astroid/test_utils.py,sha256=axGB3j6ZEaVspL1ZgPizKgWehNEREb58Z97U7mQ-GA8,2319 -astroid/transforms.py,sha256=1npwJWcQUSIjcpcWd1pc-dJhtHOyiboQHsETAIQd5co,3377 -astroid/util.py,sha256=jg5LnqbWSZTZP1KgpxGBuC6Lfwhn9Jb2T2TohXghmC0,4785 diff --git a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/WHEEL b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/WHEEL deleted file mode 100644 index b552003f..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/top_level.txt b/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/top_level.txt deleted file mode 100644 index 450d4fe9..00000000 --- a/env/lib/python3.8/site-packages/astroid-2.4.2.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -astroid diff --git a/env/lib/python3.8/site-packages/astroid/__init__.py b/env/lib/python3.8/site-packages/astroid/__init__.py deleted file mode 100644 index e869274e..00000000 --- a/env/lib/python3.8/site-packages/astroid/__init__.py +++ /dev/null @@ -1,168 +0,0 @@ -# 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 -# Copyright (c) 2019 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 - -"""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 - - -# pylint: disable=wrong-import-order,wrong-import-position -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/env/lib/python3.8/site-packages/astroid/__pkginfo__.py b/env/lib/python3.8/site-packages/astroid/__pkginfo__.py deleted file mode 100644 index fd8e1323..00000000 --- a/env/lib/python3.8/site-packages/astroid/__pkginfo__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014-2019 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 Ville Skyttä -# Copyright (c) 2018 Ashley Whetter -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2019 Uilian Ries -# Copyright (c) 2019 Thomas Hisch -# Copyright (c) 2020 Michael - -# 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""" - -version = "2.4.2" -numversion = tuple(int(elem) for elem in version.split(".") if elem.isdigit()) - -extras_require = {} -install_requires = [ - "lazy_object_proxy==1.4.*", - "six~=1.12", - "wrapt~=1.11", - 'typed-ast>=1.4.0,<1.5;implementation_name== "cpython" and python_version<"3.8"', -] - -# 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.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", -] diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 22903a66d964e25193cc571a40327c934039f99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4479 zcmai1TW=f372X@k)ryj3`JTARI8JQSktw$Uioi93_!h%xtQ5W=>7>PGxjQ0P+6z6i zltP(8f!am#(jq_`^r?XKn7`3~(ARzKQ=a=)G=J+|HRZ=X~d~j~5m^ z1HX6w{8#_fNyGR%4PO2=FnAx28kmL=8Qh4>$VyCZ>bJ!${kFNS-wt>5yTKd6+-pX5 zCZN6X<&sMVdsCpmKZ#P*=kMg5>Z4UiqzO4IR zax6X0kEbX2iS#5tnV#aO^!$8sIz7YBq_6N-^the8nx5rnb$=oGQTiHxEq$H8uE&cB zOV9Chx_=~jBR$X0n}#_5%;0Z+dR{a(-inQNGg^v{J~yA4{6h3fbSygl+~gOd6Vb`% z2EQcijn3X>-M%eW_RZ)NZh1vq5za_$%&G6)OyaGVvv z=j@Rbf~|>dc2{IV21T4_p7&@VSP-WyUuVT2RxHheG8EVglJ#5?`GyD!#ndPqut2flI2?#@Q^*x`rPvZui4{;M zaaMG@UG}j^k`)G#M?sQ|A&_7Zb|v{R#c?wklei}XIVK^6B0*x>?)7sp%tXX`W3VTl z7ZuBdh*a0}?iEaYUWhDGEKCBWz<52T&2gsBsjdJ5KTt)jh3&W)FqNmm3!*5d+XjGu zfOf$q$RZXLg^YWnLZ~jgm#HGiaQ}lz7Dx=EsFEr0dZRdrgk*V-^s>UX2Qd^A1{o7L z2@CzoGGZz#=t!DNiJ+^5xTS|}DNV{ej@ZvSbl0s|LAI<9i9i=C+_KPg1sNQ6z@9i$ zLmWxFl6VU*uacq5?$_6OSyb41Q$UMB5e_tGNTJn+i+bMu07|QX0yRi+&GRm^3|6m{ zqQZPABEOm-9HcpT#~He51(~3ikD%oGoA+2eR0e?}vzAhwPhnUq8&}jsXG{}NJ zlosZIA}$D+4&wfRB?OtNjtRwmq1B-^Mk-NkUFIo{oZ@voPNtGqs+p3KNg*US*WAMZ z@Ff%i|66fBQUD#J<6(|bSio9Z<83ieP2-oK{>0Ex)ZV#xOPe|pVU9ovdyW*WONO1Plojz%Nz(jU zr%^g_A!ONR*Kz7Ud#eLPrd1_EDT+K3tNpm}5u0|liwYV%M+Dl2|_;Z zTZtEag5%W^8pC!?%Um`WP0w01mrQvMb035jElqz&M=%O@;!(%ZOpqhLpgf6s;Q8FH zHKDv^2Y&?7T|g?MC|0Y7QP7IlX2p3?3k;F65>H7mH&{TpjH z?%sLOm7-6PQTl*krYIEAZiUdG)82tuYi5XZ#ONCE8>FlUQ!*LEO89x^Q=-|H(B3un zfaXZ%&+gUE_EEj6q41ezL#$#-u{sb|PDu!2+i`+eRa1abjy zS7tY$Tm0}35ix>Xh3L#=TFapyq=uT{vC^4@tUHZLhZP`EY0NeU8M4nT%4$0uCL>=Y zZE8c$$jEQB?tqG!NH|b$J!E-ej>IyfL`*}dKClGx90`61%Y^GDo@0dN>uA0-WOrh0 zpuXLlt9lcYdIiwEVNFb0n;@qA-hO8O)-3D^>cWZPV~#Mtw$qzoh6RZfK{T!qnX{)l zkwakz4!GMz1ve%g0=Nf=(KX7`Ol-fjQ%9<&q>SB;&6mH=i!U4^kY{n3j>C^3v=5Uw zg!|95%}>pQJPhozNnR8b+UYx%=20$cI=^YW z6Nm7$>B)2(pQbO54NJ^1T5VL^oPD9&-FX_UU3Io3?+K^x1 z-rPY6i1dUO8TcrwBv>D{W4-afN?L(mLtfQJW0*~Ze9v_8?7TgTs}<{t1!~+MFw7xc zkY322v@YmVl5YH^v59OTFJag*<%)ilCe<_ZQ}!hIfncS3JqglY6ukEr?EMEGW9Rb! zm#8M{SbTZ5dxjt0ysy83;18{7i7Bswv+Pnc!x9j$C-f4-Qh9pD>%VmIC#+WJGTW|v z2P59V7fhV(*hsS9e)rxkI%eZ|Gu>+o%T1dEXyyB4e!QzAp)~G=mJI4eRseX`=5^$Qx2BReYhIqnM$} z)^sQdv64dG!4CQaRFb?wQdK6YJd5)_UpSgJw`V8+n|Sttgg+rqcC& z`T~H~kKTN6@7VMOzAL} zD48l`>PVv-2DyOIisU`IlOnfw&baU%{4LjR!<*=DIqjBfV~m;8D5cu;*li0dO~+hZ R^4@kAPMU42jY6w!{s;8xI_3ZX diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/__pkginfo__.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/__pkginfo__.cpython-38.pyc deleted file mode 100644 index 71d37dc50ce01892a60055992975b12bd6062c04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1427 zcmbVM&2HQ_5T>+R@1O0aP3qVM5(o}*a8XO~rb!HEZNzYZqJV2`khTW_g}@cZS~e0X zla##@(q7zm=ruX^HToF3_8odCdgw^IZqrL+lnaiAGedH|*>CvG%1WQ$*!}s}aHB`a zZ}sBcQG1`^)Ke6U1cX_E1vax;>n8%%n-+84TF=R)b!i0-CqbLF*%IrpZtMh0tQT}x zKj^YS&|}NcTO&cAtpo$M8Z5I9*bVj}`-t6Sx7f#QjooJJaX(mL8!yS$C*>Wgjgp+X z8I4}in2Xru;#8`X8ZJfI9(td9!^py-T+zYx{NGyVX7DpT+^L<)=);A3#8Ad}k9 z1@|#KGli6jZ4K%iln>(EPx!>o3Nw}Bp||U6ZeV+k0<^z?<%ePR3Q?WPF!Zvb>WyL$ zFw4}zMxFi=3WwOFOH>Ed%JRzfgqB4pC*MP4!c56ovA@5AMfkMrX+HZA^_^ikxKK1R z&0?oKF+~P!8*e;lA|HG<+VLJe1vzd1u`C+#|`reUa0Io5DTJ5v@Y4yd9x^`)qE1Hb2LcDlP{p<%yAdzJFhr z?$nq}qmI>_<`XZHsXs1`UL0Q4r`$UfE}b9;u)wY^Fx#1H6o88ya2F|D;O3eYpg=_6 z>O9M&GG00QT4p?Q_x9YE^3+^V1@3b=heT#I?Am_JCyFW#x?U_!`%1Dr0bLH?yZdj{ zTIY)5)#cr>lCh#`TJ!Xnia4h+{Bw4B@4x+Z)gT zmU9Kw4KB2yNpfY-RVU#Q2o2Q|Z75qU&%Yt|Fi)z6r1&2uT;r2)0h4OLKu3ya^{Z12 zqJ(PAPdWBQ^E|vG>Xxm#qqJes!CKwL!@7%Y$6B`?+qRnDpH8>7I9AufZ);(l`{wfZ FzW@rEy$JvS diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/_ast.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/_ast.cpython-38.pyc deleted file mode 100644 index 4c2f25b01da4276cc9cb208774216a67c4f3c129..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3107 zcmb7GOK%&=5$^7Ja76KCS!=JKOYbY8H#UI?2%JC?yqmQR0k$ke-t6uib}(YM4~av*|izG_MerB#rGL_NBvr@Ol9tE%~;UavCz z?)~vE(a-CQ{gnpuzeNo0g9^qOlT7lIg(OAF2O<=lbSHHNZs=OwO}&91`c~&@C9K$Y zf-sOgTo||Ps5)2-7dZQpWy>y8wHH+_IkxBQYnF+xn5y*al1uLo;tG@g3omS_hW@=` z;eryfA_KXwCk{o}e8gl`F1}`R5%Y_(ChM{xo3bS@?D>b{&ZnB)>T1k~-Zc>g9uh%1qJWVRKi-xR{DwDP7>&ouKpw*1j@`;=)A3 z{gu+)`g-M_CL>D^UMy7U6#GS4J9;NdvfaG&21%Cdj$68gN_TY)t2NNd!m52G+J$4^ zFntMA({H-Z^MUFXst32`nd5{hbqDKS#Cxjf!cd(jvP%}<9q#K3IOJncu>{6=mAiaN2<|ig`@jwOcxgTm zcddQ!&a;k(OGkv7C@QN_G;;*>S`@t;#p%%#2dCL1>}BTIWgMm{8?S&0!d6hXW8HvW zwnka3_oI9m_0qT~fT~7sFq|JZck(=)pJ?nP+5EWK%QK^XYmRs5h_W^x($b&dw1-M? z@*_h$kVVvOCOn7%9BZv{}}jeqedd8M*;-0tOC ztDb4oc^Fs-{iL1mm^h)w^NEAmK9+8d8>{oyt(Oagf{5liLNCA+O{J~l=_ctEHce?b z_ekhlH1Pp3!p@A5r^{>q1{P(k-S!yUD_Bs_R!juk6%DRGgpQok??aw)PX!Z1);(KL zCakC$cEB^&@B=>K!(|$gYYzE=K)R81jBBN9JS#opTj`t1gii$0&YgG@|IpuNZ}=wC z${~=_HOuSKF%XoFO|FY*SLcHxw3RpM3b>g<+|PS{Ejj|pc@J+y0L%Qqb!z7#zh6S9HInFLV#Tncc&6&%$yaS5cGQ~t@6-zl9eH&gz*4m#Zz zpGpb7J=zJK&D@0kMutja-f)|XXUx|>!V%jbo3xDE@hO8ShpvLGLBEFbpA5o0%00Lz zeQ;k^z|j%G(G|fLWEC7;5gZ*699=P~6VPy##-_fD-KYHHDW6RFH&fmni*9$y?@#$h zCBHouw{Pn%R*c2!>R7C=cj}=-SM@(j%%_%7Ph#_A zl$y{%6AIm#x|RPXbjVTu%trSTHD#m_Nv@J{#zSXs{xV1L+F>WVW zry7a}FGKMN;dx{pgkmED6`{9L5Q4>H%s|8qe8uIarW zIOQY{se+PI4DXW^kd%uKBxNJ2WnWM}>W{Dxz0`f2$Fi&(HRsaXMyhR@aFHckS8Z>}HQNCiKlZ6Sa4JjTpJZRxVpD zEPOSg%6ie7Ifp@8E^XHeR%f3T>jdxOGq8Zy>>mXZWm51KZ*bpPLfdkkhEt_dIbSfR U;-BJs_v-RO>oPuOE`pl>0!B&4#sB~S diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/arguments.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/arguments.cpython-38.pyc deleted file mode 100644 index 955441e9654a2a7fe7e36aea70cfcf3b2627245d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7669 zcmbVR&2JmW72hu|mn({vWm%3BC)p&9V=4-jq(JMchMUxG5;uTzu!AH-4SLO4ic3+u z^z6#A99!Z*5rhAB+#D{E>~RjIF`uQhei z*U>kchUgpUmzpKfFQIQXO;veSVJ0izR#DZ z*t-#9&h~D!y+Q1UK|~Ni$UN#8>#^T&)4uVKfx%1oMwifdN>gP@Q)6mVX9tAvPb^HB` ze(brw(-h@w-;E-t6LM!gU>=WRH(-9S;<$Weea#Ev$Qb~@V~!uhq2oGjY<42-wrvNW z^RW|n9*gpo?B0vcM%Qn59U8iR5IJ$z8$*dRXhvXI^)@#`&c;^bt{XcW9{2Vfz2aZ@ zf)N1?NkHIWx5ph&=La2hHfXyW6bK#e4Y(K4T^8l;%K=Cv4!1og>^RG9 z;{Ea!H;Q@avqlErAo-k?`g3Iw#NayJu+O3b&m=QRb~IB+MlvQNB)?uO!`@nR2V)d5 z=F`30z7Q2O7V-uU>6(ip_B$OOt~twY9P@q1m83SXnY;NhlAAd*B*fUUUy%_R6Xb<1 zwCQ!^9}^uKpT#%gXcCPns}`^N%1}$RL}@9B+Ea%HT5VX0^=$=nMxyjeiIM0`y-P4A z#^t0`j4h@y{Wc(b<~e0s1w@4ztR!Zv9eY>FW~Z2fw`5-6I!o@t?_)SLvXx;MbUiJ zUh0Nx-csbXxfh3lx3uENEhu&vEv*Os(!gy)1=if)xya+!J-*}x*O&VK)uq8^+zo?o zG)^tin|%&&tL};yEoC~ll&eS77;L8Y>AoMu?Qm^y<~bstcx>+={#78+ACRr^!zOQ3O6EW~0=~EK`)~ zkr$_j*!rOFx82xdtzxCxS`Ub)WJRL1mW==*#xwb90iVwhjtv1b2N7mZurNhYT7t0F zqV!<4akNr5QzP>Fopg$xd-kUJVO*XQulYPRN2n=uNAkG&GE+E7oFM91sI zi^H4Iw*LC62m9>g2RPx?p4X10i6J{C%{(m&GnCm?vY(%4PW~U;nwb=7RyTYca@BLz z;ou7EO4#5`U{>2O_3(AUO5c;d#Usl-aO1ADNCYV?K)saOnJm^qmd>0fM?}Dx8BeF^ zI@w?(qq>pm?S9m(w6WSEn=6I*BpA9^eibsoEdu-|R>jj)>?*{zHA}e3pEnASiFZiW ziDY+{_RXP*$-W_a5P!98bybI4R5t+N*{;`Kb^H#lD}Bm3ykHQIgf;G#7yJNE(`O5X zBaEaEB)(kg`Vm}G;H-JntoLJo05-;5urq2nufS>LzHpHa1dx16ST95YCyDv&m|Rgd z+&m^B=ZJ^^I3pYbL&qE;QJBbe9ypiyI=nIwL!UPQ%RvzWG(i`{z9DyyM<$^7nV3{U z*kg{k=jx`D8Oy~27r9*ThP#FvEfN5QNE9?lRgSXY#|7(vY&8fs0taqChV|(8H%BDZ z^;GYB0e=ia;g6uXukt6Tzvt~9?z$1Iu3+}a6r2NOMD9khwjL{VU|-O$r4OC2uMe5o z+D|Vg1z(694~^_Hg(7?tQbZJnfYV!n$bc+zAmNMwg%D0IEZlry`Nd%!BJkQS-mp+v z0lu~#2`M77B7MulQK21c?yAtkQ9PCD4j%ou=1gb|R0Z*<)HHvk8;?UmeG8%{HQ+&Q z8hbzEdcf->c88irsac?Aj~2|0i#Fr1$YydScywPS$RQ`}H=!m+D{R6U2pUlnZ1kX( z+i+M2_~;gF_&MdCdih~^ZDWYYiDImKDt~@!E;f=9Vkxrguq8wDEhRW^D6!cquiCt; zD)bXuy$Wo50kw!3>0aoO_0(h}SU<#%ljNSJhMaObJrNbBMu0KAJNXA*B7j=qE56S; zat?|I`4p|#K5UB27C1#>sc{Z3gg;K*5_}1C`w;bYbof!xa~Z2wqzMr*0J-SY6!BAp zvyr99Emm&bkT3!##WP3~skdLO#VJ~N8{g<9Gzx--Dnf^vYHON02M=VUSJiA)(`srl z0~pNYtyTrRrq%$pb+k~^z2VV>iqe%yO@)fSkIu>$sOaTi4Gk!y5tn-Aw#I+EH6ND~ zqetqOD`*J{bOH)$_ohY)n&>;#c)C|35sy?fDbXB~iCg3A*N(*pk`mLPK);@x$7lwR z;h<0yD8x=RG4ei?Lzl{t8eTt+>a%-Pgj1-^QL<2^l*<=m7fzS)22GKK`4TmxEu2E# z)N}^}FJNP;Qif@u7^xXUl9i~K)0uX+ zbPM4OR$+>cDmzHicGb6#KR{|F$n2ba^w~2PsT+bA6Je&+vk=A@{D$aPq8kD;1)gJ= zfw#!j^>ylW=n);$4<0em6ZTx%94-3K1C_uPnDl29hF(Ea@!($cd9Zq z91<>Lf-0C#enQd+^LBD*C01`bDZ}6>{F9`-Q={>&I;?_DNzgW3_Tm z<8$bhRyAPx09a<2Elkx1iQYRXAXMI@{?HC=tk3QoLI`fhbBP@v?#*x0zIVm^5zJ2| zQ;EIv(5^J%@5Vy!5v=N>N36EA_GL{Oi1b@I-l zu;n^M849mVROcLFuN}9Ia+N6CA%>wGs*ON1ujq_o@|W|P-l!7e;6qp``B+BK?v2j4 z>QP8bm^?O$RcHe_5(!K_DrM1`1x*{>5V4q~3~`&plY5*=Oj**j>=a%wr#g$Ji@<7Y znTX5J$TI*+)NT^}Pw=7RblvNoQ>5t>I8tRXY9P;&DHhd0QiI^786>N?^@B@c=%93h zFuq8|zxW_gl4Btfi6BI6j!sN(#Z? zl)*Ua8&n*X1Adm!pF{H@@ptPdBW>xpKGaj>>prToGSm^}YB_Okb9rn=<_< ziZP@_Bv#7WM)hBzV;QD`#Svf|@URZ(X&%^vho8YL|1LGc+Y+yl>zRE&@Pd#^1^rgo z=}=Y4M7bCV_5S`y*5j2!Qz0oGt_)RB|8oZ#6E2 znMvw|_)mvak=%;jBs(@7HzxH35mJw$E+J_ViKW)--lh!J>%?B7K-6?7(&iu_t#+V` zM5&0lzenp7wTlOy>Vt5=zk^|F#G3;ztz0E~MDgb}nk{wk{{wFg)6DC*DCNjBA+1~pK^9HaYa-TcTDdQg#*7p{wMWw9 zuVbQVfiqx`cOx}r5mas?hROHx20>Nj+i!_Gb4ovC;Y`?}muV>Kz_m%!_Z}9azoAhq z8;OdR|9os#G<6n9h^fzux~HaRYyUCrc@f~wBEYpirBPMC9p)|%4 z0kCag1qskBLSs{_>Eblq7@hfVb4pfMjsKb@L!J4|0L+)cA(aAMbHIvPY)-qXeY|z# zbF3&b&kJ=m|E;Dd^ODlFTB+S?p%%H`r+&57y0-52vz2nI#lm*0#h)TBl3C?c!j<9{ zYC#E~$Om|fdLwrvdcxRKy`9`yL=6hbGxi~5d()O}+4f2M2&eT6bt^4r#WSI#vb=d5 gOY&h+jwjO?0^jeP)H*G1afWi@h-wy6I%xI(0r?;42mk;8 diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/as_string.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/as_string.cpython-38.pyc deleted file mode 100644 index d1a59359e8af2a2dcccf9140bc87ea660d1996d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26097 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 diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/bases.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/bases.cpython-38.pyc deleted file mode 100644 index fdd525052e3c951330834b3f702a3255f7c2ba3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15940 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 Co*m}^ diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/builder.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/builder.cpython-38.pyc deleted file mode 100644 index 093b62c8294e1ca45d7fe43ff9b9bfd5aa193ba5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12905 zcmbVS>u(&_b)VPn&Mub^QM6um>~W+>T324hv6Ci>sz{coM6FFb68+jHnGAPk#U+=! zVF`<*+p z+@+ZyEv1>gGjs2`uk-kwbM7mXlNAGhAO5```aij182`$L(LV>7Cu+l>?9(eN0)JQ}_)d^CLQf!TO0d{6i| z-n=J#BJ}Y4cz8N|GJG$-JQ1D=Pll&Z@2E%2Rw|^klo4phUbmNc$+C)q(2Ijs zBu$z@_e|m~Mc!r{gNa~JhJ;s#ZbykPq?Etb3pYCvUKW;uIEqoIME9D}deZK7`BYj9y20&8 zq3E)1((dqeRRwo_8NDW1R#7$=d@OW(p^$P|JuT@)h*Qh=`_{?J{o`xxc)b%eIj604 zP8E|6*kco%HvB7~RK|4`S9~3}#2A3L?pt4(+cpz(V6IsA!I8&}ZR<7TgT^O~o5t(9 zjvX2UD|8+@+xEcTv3HGaXJ8Mkfzz_FhlPdIQcH?mrKYM`X{j6C?XJAslNuAz$ z)KwNMx!e`0;ILFHq;9L-iMm+r#>CQA68YHqC|Fa6Si7hnQYQ?O;B7-4!^ZjvK-HFussC(ypr@eH3eJfe+b)T(& z_qNh=B6}u6i&v@;8w&?Zst#pP1_BBWN9N#nOI2I8%tL8Ct#&k_}0`HofRQ_k9 z;Np@+zKlY@Ixuz&EEyKHJLedQxmr=4Y4G10M)$GTv9#*qK$O4(l&=~0&DD~+7-DHd zN0xVN7ugv*xrHm9#cdh8`02_v_s{scwSgwGMC6-0L1#0 zz8FVIv$wW>>0=~E4OKKOqkqzes6edZ_HFzmiK<`h^qN5@zEmH!xV{L=1yYUE!wbFS z#@c!(T7wit;k;5kRkKrvjGMY7z|B=pfd2j=%lC1?+^~#NF+3JdgjJME z;bb@kE#-#O;S7GunZ~PR8gJr@hGR6U*ox!n)VQV!9)RnwcCb)h3)(0bU`XIldx4W9 zt)?_9c~BeCP;~`VY>}t6M!iz;@JB@kZ4#_`Pi4yDDKB1+n(bB_T9JAwd+jx)=ex`8 z=CT(r_cl9WuH5QE=|&4`a9A5k@isc^o+FK}5DKGKu-QpGNRW58-RTUQa}Yuz8%VIe z-r4dK6?9`vbS-|$qZ(9ekn-4Tw}jZ<*S*0A4K{8=IRz~=$*N*e?gp`}STeRexl+$o zM(etBLT70Uz3KrkMYINsY7?rNYqqf1q)_C4Ea!p}KaPjQxNq#3yO6noxjvIv1H-2R zGkhn6B)x4eKnWG%&Gks7uJ5i-TfluNJef#X%u-jvBkBdKF5lq@M=X zu0=f$Dz5s%z*unyCUt#ScxdCju~L?|m7R%!y^FpFv;oEb`R8eSM>${YwrnH!O0&4v z?#4;bZASG4E;QAu@7L@f+t9du2e+o&d+Pm|+1oHBXhzkMI_p8QT&t!f*jnn7)au3R zSyW10*goj;dx_%Gq=#XNlVzWs3wdc>jPA8#=&6cyC}NsUVknTRM4Mgp6dJ1rm+nO**}(8 zE7($OqzM+V9y){Kn_}ied%O7g;_I|UD`?{+g_Z>i^@Wjk#nAb=?LL5ZCA9fo)@Dxn zDu5-653K|Gv0(G;uiSwwT3|-^tEMXU=fcvCo0NAd1F$OCiq^6Yx)ZAvdCm7A)(0gkgEQZRtZP_9>sl-K?`2FoiZp`^ z1!_f2hVjm}>rq{6DXrOST2oW=JjLCA%7b!^?vb4|umr{oJPkH-a-<}>imm!5U+D%* zAPo@O=>elkKc6G5?F*I9MKqw>HCwZquz5k=E%cv%Ss;w}te1nU+&DA^@_AB^24=In z+U?!#4(ko+_Uo^y9>KJtdDu?|6QC{o97jaq*{;`2^$6H4HR}TMYO?}+($bBW#Lz3M zqjYYRdm-@hDV?~r)lGtX*~1IH-sKe{Uuie!`eF(BJF4pM; z@J3H1QdNBrBM@O!AL3YCVs8=r37@D@%U?R-10QDcUUNmJbt4gIN~R!Ab(Az9&P{cZ z@5W_X5udbh34}HZmN^S3=m4w8zyEd$)=y@Ob9`gTo1ZvE>&LUD83?^)SnoKN_0u`K zXjM>u4lN(Irp*5F(Z!2Yook;B+Gyq&2Yrg>A8P;8ctLO}`q>84I|FkEKyud{I6jQq zj!j#zOFzr%pFV)qM-d4`0J~Q27dDgD(;u!m>eoO$Eedx;x#9#ikJStKP%G%=<5KN0 z=|St2RyAcko!>@%ZSpYf19aYK-7%dvX7>7^LOJ&_{S|YE5^vJ7uh`d&Pd`VKv_d0j zspnBD;N2XIAM_$>6k+CI4ozd@92Ur>2}Ai9zLZgK3I@`E4l2sqMNpqmcchOh`yj}c z#k~9pc%U6XpP}&3BMqZYum$lEcP&FZL2me#iFP93E?S=?t-$zgCYy@pZ!(>f4bO>b zGgNH`&E+U_DAQTLE&Q$xoAe;-4(AXu8mChkHC-!C?H~-(W4L7vSjkU%zJ~GXjGqmb zAYbh1^u8C`Abym4t<9g_Tye?DVqFE?7vrt9rCujBec)(4|NR0(e)&50oq}XoMY9U# zuK?JC15m2kcw_cY>=S_zSsjyr3D6iCzkk6)e@@U3@Xtd_Z!=8CC72E~u@bvw!!X^< z4AY6kSt*3JmKT^o=V4)Jo`8)qGbrXMEC55TB*hh&CBZqRt`invR;-Deo%fMi6_Y^P_TJ^pwttxUCjI?Wp<>N+JS+%y^q`ET+hMF1_fU?Si^3L>t#vs!k=mEfvtQ$)=sVGZmuj0{2*?JmK&n1Of^$a9k6 z03ZGx-LklU@@0fOh{ZA!BA!SqfUXILwxQ<0;g%@Kh*;A(TDQ? zrfMvtKo5b_w{gYa$BpsA2ga8T@o??XdEjnC1+ExSVBdfQ&<>CjE%gAw2Uvt%Lm=S^ z$OJ$jz{u=a_t2re%5!&^yDfk{P=QB6`O5dhJp)p}_UR^5zZSoe`n^fJN8WZ%rO z7*)4JU^Nyi0W=0`%wi>6Mo1nYpn4yQh>uiAh;gWH?`=~9`f*#Ix)(da+EN%?`UkZ5 zcU(sQBm4B!&r-1?5tEF@yN1RMJ&Y@!!Hq-v61Mgs7MMP1&0@6CUX8Z!<8U!*2vw|Y z`5kyNZ<~#>k58~6-R6kDF~NG7j{iqeme7>hzxaP1^a!EUd}^TvhZ6MCnXs1|qD9|<*;C&e;X7PE(Ufv4|!|z&CXm%b#G)b236(bq4_-ip1()rVO{m^AtaSff#5RPSZ83TBwmNhjK|NE%0} zw)l05vu-bKCb@wFmuImlMRb}L(Ku2`T0}qy=1luYQ#UwVz&zb52Ua2h1GaMY>@YC9 z*@+v)HlbOZ7A24y?*~@Djwb(vE53{yJrNii2mrl~BFs?{|6q0mU=>XlP-}`8Ma6dC zfp_v#%bxikt1xBFz=!ESzE52C;X&x5#Tw#d_;0BN^tS-qiVzNW7_l8Ll7CDxz>BFC3d8C#sb`V z-ALr0;e@?L=V-};?$-XE2>o;;mLvwT*J!lzQm@zX_QzQ-3=zN;hN`8%k$`kQ1O~um zCUx%>Wd5MTFqp00=CF0xV~X%@fMg(h&*RM_q_BjH?&z4dUI8!&nMVEJ0GMF>D#G&Wirmr>%o%dmH(4ZCyShTXY5 zFkgjj={^Rpds-~(EU3?r-nU zzj*V?!mS(g3yc2sR~D`=-gs$2EDi&+NCy&ElZ9c&(~W4sBz zgt|zlB^-o`)_Qk{l);a~G0U9yd_jJrd#Dp7NQ5FCOsEV>$eQqLKE}O%FxE7Ry*p1u@>q$+SsJ!^LniV z#u6h1B?EylFwccdHfFPLVX)B%pI{Mso83?kBm)VD)B~`&*3!;ZutVx_rBY`Bnn)Yu z!v}Cj>ICX`tnQ#~I?YoAJcIxzkfT=g>r#hkJ1r!e*o?FsbvHpSNTRd^doN*=Ds%tM zW%!A(>*<`I@fv=IObVb&3*SIaKj_E@J)(j%OYL@euQA2_=Cm?e@)ypEs7}=0|I5Ypfq-hBA_QApe4dsC<0g^_1wU*Af~sBjpsrMjs^dPfzE4@(@cwu zPa>INZgMaTS0nX_w4-+Bx*kL?V?Rg;SyH}Y!GRLVGh{ZTG84qaV)-Uwk|!;33Sd)p zqwu4`GCj0cciW=iV=vzwkD`i95jT*DD)1P(8A=o&D}^cwg~W&!_QJ77Y3%*!eo1W2}FHSzees#QgU<$PFV&3N`Nl zDZ8L3?-#rSMLj1itrrki-xEbwQsdX6RyuJ#Q?__etKdC&f#P_pZ}H(Mgbutv9G1UC zKernp%uLat7xml{?wfC#poa{VQeQN2IDtnJU<-NT18)mE<)rc@WbsI2P>8>QHwCt4 zj*IUk+=JjF+90OQHp#>QRFOlo)DMuntsJMI761k(g10cGmo*ra(BNpu50U6$Sejyx zaTwp?oDq(Eh=9-*YK<>Ddn@OwID=Y?L)Mhz17NT-x^#)~%e!~BHUxKk=gHfxcfEz%C`!P427L{E(M5Eaz26&I zt~IiWM=&NC?@O=xSjFpS_1S}idS8o@<+IHC*DkO#jER4GbRLXp9Onet|4_wfg5DW6 zKQlaVv40fvd#2;vOC6}CHqeaP8bu@LfFzJHg!$mAu7NTDG}pI!L!b+e8IT$h|1s%C(#59q7-EwU^RHAp6d&p&yW6lOm9H5Ka%x&Ij2QrGh zx+X%NIumDz!=n)uKf0#Zqk|M7)cdN2CF7&Ufsu?vgfm?vO@*#;L#wUg#FJBS`DPx- zQGxd>9%lc{UIv#t)C87Hw28^*xPMo&{nZ>9{t9TcdOfIjRRa%0^ zHv>)OunjN=U<4eDU!W`WaW**TE$wH*jHTc2UF2+#s689hYIs=6`R-?qVth%@py|)% zL|EccV*!vh4uWY=AqA54*35$gNx<1X2r}@qY}UJ_E@y{vbDz^0Q6LN=;c#Z$3=|R^ zx&AqqrQ?AG_wlEO067XDHmK>L9Rz^mOg9L2j}sh5%m#HGGsX7dv{aj*6#|A`1Re)~ zAtJ=UF!jwYz5Ai|81aMY*a13w>+MJ*-cj{S*Ma8+D0KuPnyGV*T=!nf4q}n1@EvK8 z-sWw{GdPlSsB3o;E(AC}Lj@XB&|e>MCPzH*Ox@~_SsT3#8EP2O`@*_{%E+`bNbOp1 z_j#NLJDlOMI47my!9kcukjH_o##~mI>%CKr%*5x|6b|Mr&?q7tM4>uz?~FhUhuTs- ziWaKF+c znplwU;b(7P>M!y5{m~JLLsqM*Z{kB*k)v4zY%zlWQ1t7n#rKE(TZ>l~=U=3!erx`P z`KyaB-Be#DWyUg6XQ>x%sgOk++)5Ze{Wc$LC@VNqzt4)?n8viCQwg~Z1ue$vJN(2o zY?QMNio$#rGV;G*1zFPSCK{QMo{>iDsD6j=2?Fdl9YpgG&c||X<8V_SUKEaJ zA-|S5t9E>CV8++q1QncL6)Jl)-8YpXa!^~e1D#EUm>z5K$JtMk|V#W!A__pdB0yo6mr(8Qm=dGn>4XeOsSKFb!% zY{8TcG?FAtH4liiaXHlzZa?5EG9t_Kj26r|%QGw#XC GtN#m9%d}lL)U?4mVL_|RTjpgq_}e~q9Ypl2T2Q@%ogwEevyrPb~>rJ%M?sNRdQZ@L;UtB-XJ|>p`6MlQECe0Y-a5inK3+DCI#vN|M<+)&3m9THO{a{Eu=S zXK9r5>CNIbSL{Q)6&4h-NSU6)?Viimj3TU8D^=)u+~*C5TIWr^L?VmE<0fC`E2q{8 z>n-tBeg$urxdTP67Hc2OWZNn=nf&#k%no8MW+DcAnLN{=*$i-P>r6tKM2d(Xl^-RP zPctr5ptC?l2O`k%NSN7o`~7U3YQt!@<{(xv*=xQ8Hi}cc3Y5-rVp%>((H~0%yBJO_ zuW<874~u4!W&7hijYgtaB7;_bC>p!iiWAquH)e-i#R@zmqp+IO?UO-g7maQFxA0d# z0-3Vh*Vc(OwL%yg)Hc*H)ScS-_hNcmGt}eOw)Kj2TlKuPnKO+ZR!1n2kh7iM|v%OGRf8>rje3Q=M@dck-yOhhh|^x0R3wLUu%Y z&`ILmPJX0^S^7@>by_ zsFXbPQ7$%u-7HJaINwc@>`(nxMY>N_8Oaf{gPv7 zW}ji|>>>x9bBZ?RhYNrc&+TJ|kuznXgS(5ni+c@s{DA`YMmJ+mv)_l#3!7+f?5SOZW~0k`aeGikzG%%ok*lN7IK3Ad1zCL`_AEj6?1 zf=48Zj1}TvI;6hFeDj-JzbHZ5EI$V;gaPD{KCOQXWMCaTQ~RE^bM4rjIxnoLOGzd39^cW5;?Nlr6;OvW|qA}m5s8`DhuN+*kP;td<6V4YTq^${G z*M+T`%(o}OWowaaXNxXHGDWko+Zz~^k$l3A0mfu20F43WZA;QdEn6<(W;~2BC0Xfh z!qtWBT808tv_is)Lwr*N(3ag~fWB{C5^-_%CHcs=6jqAh@AuZ8X)sRxX8^)`sIidL z(d-#U$UgT4^6n+uv#+C2v})Z;%%}{!L(EL=v37nyicXmZdTRR_Mkh#N4JIe-1~BwF zQ1-ep#1q?;aCcI>seXP_eNNDUHllVIb3N>~+``Lq35YG~IV$)l!eAhDq_r%ZM5Had zu-k7HwY^v*{1q!LXN+dhsIf^-eVWTVza`;FO4qUfZL>H3Gx^~qbA=%aP8hZ~lMKaJ z-D%HPPrRGz)=kx#cWA_e-xfx$#wEwd`)UwIW+sQ8dGFl<{#wyDf*|lW~+(dxJ60`e7))PkUV< z@--ra0`eOmMYF8lxzq;!62Vnnm%jkRo$y8W19m>NOCbxt`l-zU^P}SNtWH zHEZTOMf|yoLhOC~)texf+CFdI_E95OFP65@1#MM5+;@JNCEQdd<9UK*>f)lZ_oQB- z{mL%fNDfrtBj*n@$<_bqi*7*zlX%wDmTyo$eTtC@b~|+eZT1wkAN>-^;!d8=A$uc_ zWHbssjFtYhi>9pmU?-qmHv$qjK!by3nVMdDJ06KttBY$NrI_%k;b5A@_OD8Lch-Y0 zpnfNq$zSoDJgL6nRI z0`t3gDStxb0=_gi6X@8_M){pT;j^MWJT#V*TMK@fcT@|BGGEq}1Orv0Am61ueoW;2 zMkX--fcGWL);#92HQQyAYyWGX7CKYU1irjYyxK%MM9zZzjK3LCl1aj%-{EgS67g!g zws{A8)T_X!l0XgGIqOnSLg>9kYp;V$QOoula&2n8uwKIGnw=01+LL$7jsp={9iY(R znf_}%K%kba5wCjy;$b!CsqVr9CLJBHMv4C^ZWruREcdhgXx8fgh2$uK9<|$+Kg096 zZkB|d3rxvLz>_AM zx!ngF6_+wR03vtM_8rc4E!W7h<-b@9%twR|MSwY$VQj+ZD!n+%0aIhHp{eDw7z%Y3 zk_;~}v5cjwKAHx(iRV_M%qD8^Bps{@58J~tl7g!2Jt>#UZE3~AR`YZ#{LQi^-Jzb; SoXx0v^4YSpdbs-9HUGbQ)=usK diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/decorators.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/decorators.cpython-38.pyc deleted file mode 100644 index 892b8ba77543a7dc034577388bef7c499a3ced77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3601 zcmaJ^&yU;26`mm}ijuX;)-9ZFks3@8$54|C0zGyyU$9&lOB@=;YJ!7JE>O3 zx#)$r!jXI&&a@oOvT!uZ6O$JCU?R;yAwnUOLdB*~y8mwo%XWIaY9>W)*tUTIW`G=3~yJ1hL{QAPLnCfExf5hORn8<;aiIS$sU8uVCy;D_8r84vQubi>)Q&k+LLh3NCT_D2s_fS5XrAKilb3+b-<{?a(9H#j` z9Mlf+yIG$Y#<>V@uJ^qc?!i@)Ldj5$Mro4bfPUMqzcn&ag`-qy102Id@7ZH-thYva zJdxYs9*0Yh)9V9ZVw(1AVDt;MZ^vlt;Z_OSbaLYV-}cG+V!M$d`>~3rQz;VX6hsIi#Amnh z=wF~gl=3lR@;=Ldh$!WV((9Zp9nKaP4X{)4OW>r^`NFx+J_Nrlou|$N#A=SVWDtV|s4&0pe1tdaVXytc3Ch1Js{ui_^|2rzr5Z@n|Ak=5(Q1_v^)_|Ix|{vXhWo*FVzeM5`ZQ0Fq{) z=1vLuOZFV&7kud&xE9*7F{t?11u46`>?;nwtS#QuE7JTnPUv~Hq#iM4)kOFhIID6I z`R4>DXMB9y3ap?L?7?x2ArUC#-cU{T+Gc{Lo~z;eT$!$dCt zh?0#Q;RyE`Kjupq4nXi0|3m_qsoZ*gKRp6Lr1^-rYn67xH9EkI2cSQsGh&EoYz}HN zx~HWe+SI0))_WzgP?(PFy1Wn)`@p)HlChYB@^D2~6o*pS7>`XjDik8EzWnpMbUU4J zyH4q!)7eucA(^4$DOxCff}b>!yglPAbXriF0_pd7^xx1>eg||m$r3LZY5v?Hi>S*2 zHZblnL*~a!$wxM$FB^+(5$ zJrBy}3(nc2Yv7=p;Gh;b=r7=)037sI8I0TNPt*!`i}~QGhwRUt-TLj36oM~G{v$p*yXIKwVURo7AJ5_LZmG>2q0+L^Q^$8HHHqTqL@}@I=P`QYU%F9tP5gL;$ z)`Uh2-XH=TpQKV$ZY)H#u?x4}MKX)2q*7$pUJF~{Rz=J+Y(#_ zbJ|j<%0=NZL`fob)sR%NoC3JTHu2bv%!E=062#ymts2Cg%b3S5k6YWL5 z_&$LzTG^(5BP&ol>Fxdss6D4@S@0G`hC69igRqE#EGeA3zv`Sm?GqA&xQ#UfzPY7{ zmCuxqRDID=2_Bnz)@2|{#V(lFJLUukfZ*~f5&gI>7mYJ^>B~c;A1V<`?+$vu!VHZS zMJfpDUA)wQ8X~{y!oA!^W4xEiUZd85;BEb2ZLX+DIhO+>?A7UB4c^9k!{h%2A)JS% diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/exceptions.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index 3020be1e3df4a76200ce5a7c09ebf5cf5ecf2c81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9211 zcmcIq&5s*N74Np&A2XSmIFs3YCtJzxCUHn+7A+sUqY&~95yV0HK*+H2wq50!p4i>q zs`faZ4-V{#J%KnNaU??*;T=d*BGFjs{#@HlIEb?M6f9}uNGFyrC2kN%x$$2wxnpeA-ElKKRLaj=Rgz&Y&mFgjU=eAhz90K(UC$4KlJ=1%mP8yTNXw?31J4EhRZVO`SXn3 z_C$nZ)opbndL0O0D3D^Ic*6imq}XH8?*)=y3j9_d+%0w6pr__FAGh4ba>6`Y#%PiT zl$a7B3!21}&t1t`ljy38tlkZ26*b&SgQ>RkywMA7mBtT z6tIYH7)p$FNNiaIy+QVIPvIu|gPfM+xjmSu)wKE6YR|0~d|^3giv=YbQiOpo7M6e< zh8n1auJ0{$+y=DTcKu6A$Wvubc#4{K;5)u*qh9Oah!W=?jeh|xaz3a6&JW7YewSOcl6NN$@f_jM1@W`(3 z))CC%TXmWQ2S`Q8D0sOP+)Z?R5XTF$I}gD^s737+6gr_M(##^O;7-wn+%wuO!euvP z*B(3^MlaxGP1hq=#1fi#MOd^yFS1+luEM12QS{?oNl`S3ewc42y*P8*pn(uxyA#MT zCb}MRv^hWGqqG8aX&;@#1NrC*e6(qAWPWbjNGKvBd!CWBN_v5xXN_%8`91iB9=OOJVxE3P4nQ;sCEQ4~JIF(Z_HSH>h|tp(H-gWY$@G0Y9=9N@ytsa! z5}mXpdfy8Ih8W*B3@LVgU30cs)?0Gqv+KmbX}S3sokvpqm#@=p8&A1GOR8gWZteK^ zLZ$uW4Gb+8x3j82PP095h*J}WcXS$xqVEz>sw~K99NTfM|4Mp4W^{XXodsg<19XW2UqMI1ds9g*_~se65JF`x7!NW{uG%$ytvu* z8x-x&DfR(3pKCgc_y8Fe_J5>Jl)ut05oMZ`Rhl%9QbUcfim^aK6RMAqGbKAy(LNt9_Z=$lYhAZAOi;~`qDUJftRT{={8&e#52b{JUl%71R zGp^!Y8E6H%6VSPS8ret?rjcYpFD~oI0GU?X)E$vC4b@9=-ZlE)i>BH#P>bvus+|wJ zdQGU7i=I_nnp3)TgNk1`x^}LpDx@r{(Zc+ZkMQgOCUE!uz0|5l8QRb*_qIfO2`VFb zJ!zJr)eT&V+=1IqEuP`ok14~qZz8vUW^bZETFI=i4T z9w&v!+{jzYnL%d$?SWlS*_*C5CN5Kb`lKVT^a&pc?N}LW?NV$j2n@Q~n7`Z#P>iZ8 z^T~|iQ>C1d2QhWvtOTA9V4eWGy@i^jjPnUDL&pZ4H}*gW%sXU5gDeaI{`6&Fknhlq zf{P|BDKi6I%95)S7_18-wUs`VJw04ep*Lwe|0`zKN?Um-7q;_RLy`#T@+pOTxDQ^$ z*T*q|B<#`KG4D;n-VO=x!JA!_^bK?lDB49C;mw`AmdYa@PhiwkLi@z@ZWQfGCRpnC zyY1s&1*bnI{>i$KV;1va}?cnP@TWQmkateF`V#QZ#aq*YefmYXDLf zuWLy1reEMPnK817p%UY$u|vg3sqM~A^mTmwDdDAZRwut1N$YOLF!vkB(vZD|jgBBh3Aed!6y8|NZaL`4m~xF4Xmx4mT&FHR*)r+N{{7C{7= zDxpFHC1S=6$FpF9j$8gnj3*c0@OiGjRtt2yGBL}doc*0iwuGgQ;u&6 z;}i*M&r^*}{d(#zCygrA2s-g>GN+L?Jw*vUfP($7*pBc9jYbz-r|R{+Wki)1Ne!ZN zDXt_O>_38&(Gsi8L=U!7IS^ z2ckb>g7kLG1Zf+;N<()_7$2!&WQ*G+Pm&x$x6R`Mmz=rLRbkLhZBJC&Q}s+EJ)i5` z)8r&xsKb#$GXrh+CG_8MphCka{=|)xx>$Bsz4$0@muAs*2=QkUgmjK1li*jD_E@bF z_%{XbHat|S5BnYQZ4c*cva#G>yPuBco~q$QG{gY5fE*J5GCd8N)-aAkyA5+XXL^)S zKwX4AK}VlGh=`eLw`BAN*#ApP9D-k2oC9%t8^^Ozi|%S#3N*3q&?kKWvcT@ToeovZ zJV2gL&H~lrjKrsP6Hg#0j?{MJ`6hV$Yl>%rUzz7p#4{=1q*3pUu*{MVtfvhJ{S}m& zIBZ529tQY5eMpC$6`izQ%;gq%`&)`vf?t`}VeWDd=Y&0pQ$fS>4@Ouf1;*K0=yj+j z38L{RX3SQ9gZ5NE#L=!k#nz2e3a7)fVeKrtNOT(#{5>TR!Iko9eVQ^TMC~j|-Z7X+ z`n3AoO`n}ehA;9A-OkdDx@x*ZB&pEUHJhZ0NGHuYfs(YRNs21k*(8~$q&1hMOiA>s z2d}&Q9$Z5opxrem)YX~fjn-E62nId!@joPz_wmSsqp!{IqZoeO+jjiimiK1DAzeaT zi`un`{ZvbjeBFLpCHtq$pgLU%!rPRWM2tnYn4Dk5rBkYCNy_v=@v=EJxI+B`MY?h_ oQ`ypy(p1SQ9mG|_6a95cGo=H7N~OGpoKi85)8Tvuxhekr9~<4`q5uE@ diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/helpers.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/helpers.cpython-38.pyc deleted file mode 100644 index 6c44e13e0ef8ce4ec0196b594a2b38a9bef764b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7417 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 U3ESoHJA>bIQa3E=U$LJ2KWiS0MF0Q* diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/raw_building.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/raw_building.cpython-38.pyc deleted file mode 100644 index 36986b4eced5aee85d4c2ba876721b2d5922e3f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11673 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 diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/rebuilder.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/rebuilder.cpython-38.pyc deleted file mode 100644 index 0eea3ce620820dd4a7eb8da1a1ee4daabd23fb4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35577 zcmd6Q4U}A0ec#M`Z$5T*cD0gaS+a#a7-PKtkc17k@wYy0+49;*vW*wacy{mXYF4u| z>-%OU?PfNR$N`%~1PI|P4oHvyPJjfOa>yyCX_J%YBt1=f(v-F@Elrx9!{HR#q_jP) z0lUB7|Gv+eH}c5#lB_iMzK{F)zyJHc|F3)BBV%Kw4E}EY`0rPL@X1W(Z+H{`E8ylH z{M-*BP?_nB$||dwoz5b*o7SQ|ZD-9hXWGFtr;`Wrl+&h8}7}hi`3?) zGivi`YkERiM>3OJR*!d%HQdT#TP-*1mDzTyQ){%`%5taCY;+oRw=&n(6zzui;vx;o+3j|8yP=SAN!Q&v3hgx7t`DGU6dSiRri)hZVddo#U-q`+A zv-PFUeYKWq*0oo7puTbvy_w8=Bef_G8WQE19zE1>J1pivTThqnt+)1{TGF`o#_Ceo zv7oTyeqq*kZFKp&M1e_5Z{l?kftNeca2uW39Ik^urg89l06+H{1f5Jb(*=^8w%79A zyuJ$eR@XUgb@N?&&g$kqm^}it!5~_z)q``D&arxBzHy@7st_QRV>Oq9RqJ$gV`jNi zzrG?>x{@yT6fG`Q@YhCueX`-!F=(A-4ICgaca-EM$E<*%V7|$M=dcFP;hk5IVgZ6Y zh6!-i7o+K(ef*@0PS%>s_2)DCb$Il`?9OBD#rjUSK8p%a^v?N4rwRmVyE~U#jh#!i zS+roW*17?Md!nv))>|ibHXAcLmsUE*+O3;*+`1DGtKWch$7}O-cPFrrIJVPA&br>Q zwBn6dr8(8MuC`FeO@t)@p2?N7PIj}UufX*zAH@F%_IvPi|Am#w)H9fwnQ2R9r)~A+ zx>L_>%P9Lf%uAJfIyar?{ChexjX9`B5En56M-h*34k9k8uc&dg0rPECO{k4{QdXPP zMTp1LW_2;*akWKVf_Q`4sh*{>t1HzT5MQjW zQg1}OMg5k#TD=K1T%xW~lX$XKU8}A`yiHxNZa{pg+M#wLzD(^>Z$`Xb-KcIt{5tj9 z>aFT#CMh z1BkCy_p194zeycb_anYWJ)jODo>UL2Da6;Rht$J}uTyVVhY??|j;N!EZ%~h@M-lH( zkEwSc-l-l}(};JecdB zs-YGT->QzQCgQiLMb$!ln`)~i#J8)bltz4qa#aWMooZQ~Kzx@vsZJrjTdk;7#P_J5 zQeDKm)tdTg#Cz0x)O!){RX?MC7V$oHT0M<;e|`V-0rhk0eYn0?ygUxjAiiInQ6EJ7fci!CA;gE&ht)?AKd635eH8JO`epSo#1E;Dt4|<)Sbb7`3h~?3 zuc+q`A6CDrK8^T@`iwe@_^3LkK8yGf^*Qxxh#ytIu0D_WG4%!YMa1t=&#T`+{J8o} z^(Dm9LfOCSjU5GzK5R&LU9ax)FAW8Vh&X8XOdVvdPI3_tZjyIS`mqG?s}W5jm4$5?o{V=dl54ngx{N}s(Q1wQdj7b zD2?JM6x8X`z9_{Ki$b-8O;j4w{)eOU9i?H zK-8ME9s^u(Z|mne4r66)0|Xax3;ENQelB>jP*}6^-j+AT)0V3{Ba*{BDKRbIFBCeX zay_EEyle4UnRTILTV;NZrDv;lRQF?<)@CQu89QFmU(06r@9|8_dIwUe%p92rXUZE< z?OD)cto}NS?tGWQKBt3P!28!RR(k` zE-(z4h3r|Y13)e~r?VXl*Es-7Ux}BK1dr(m-e7zJXxIm$RiI?(q`TR2%gEF#Sov% zzROz6uH`yFNKDuq5X_#>cFCt&XY$Wxp2?iG-=BGZcFqFwI8PVZ+kKhS$d|=CAV+TX z7Fm)jwTfZc40|%O;`158R95D|CLRMnX)vPFo~txEQ((m$&U<}3n&UZhjV73mrCR5h zSMa$2eJS3|64`=3_L^O}2tSttK^pYL#9G#L=b6ko>%-Pl4hDiu$@5uZSDv>#YsW4x zH+u|RE^Z2~`biQO18yeNGXG0=G{OIoCA{k?md_E-g9xtfNCMgLAcn;3xTD#g1uJ?N zE`rRHIeiBUWkbEZ0gG1zC)6Q%(Kq7pWIh^e5T&*vAmoAo(DyPs!D8^>5U-?(<#^q5 zc+W{#f!);urG8?R~fr&zd0hWKD@Hg55`Pfl&}eB(s+9fY^6IwAP%iV{+V)!4-(yX_66Z%FCN3fW;iC znn_Wu>NlZ6l3qffTJ?&D_wPG+c>ms``Yyi6HQOiaTCw9<&{ijf?+bo;Xn&gbWnghfq*o=lr4j{Z$@0ou3nTf+6j1Z4u#Z!tt2(j*8*x- zA{W54Z_5B`xIb&1!~Buw*>hGl)0*J?i9eCG++N-7)=pr7cHPE&t4?tSl2&I~q$ zvvrwOI}8h6fk4-4LmWF%Ycy*!kjGZ)o$tPczbRneRcMdihrn}myWR0dTo4YyQJGDX zb_|G2)=Oz7s%#4vTeO8uc@Gk~MCFXN1uXXJD^j^wPCtC`b%sHQheS| zfon-oWE<8Tzm}X|%ZSuc@}K7YrzLqh>OU(GO+yZT|Za|9x4? z8u6c&5>Lndr=y7)Huz7=i5ezQ!$zs$eg6BgL|Gf3$t;Y480EXA?nrmETkei^$Ge4Y zvAdx=(cP%V&x~a=T^lX@r${+|c0<=DT=2}nvp@HrIp&!xYa3Q?7X%QdIZzjz2RVC| zwpX!c>HCPW2N?+2kEqrZo_z?vXkB{q0F*Tvk+h|0-5U1cc*EAMmd^}VO9jb^I5Q!O!9oz+cbNuK6^Z&(;PT;|4~@^d9msImFszwq8khb zk%+JVgzEVxVLbrmHSor(PVJF zEm4+g{P`uZ?1>i>Cu$lML}|SZ$4@37Y>X?MtJ0cF5|5%fy{(BCu}UW=z`IISUQQ|y z-d@u%V5aSHUNsri8Bj^87a6n}+{~cG;9&;Ble`;Olbd49m^?kj_bUvd5?$VsT{T5S z#V+v~B^9k1EHgO4;3NZCI3memL&(sW)!_q3<35eR2oL2sX0G0v|N=(a#d#8l7{WdLAjAtzcZaJ6S396}Jx zbqWjAQa#C3-Q2(&n(nuJ3a8#3&`?U_!)VcsGfB!i&`S9Xl>@b zwOUCcX+P~x=!^m|i>SZ}+JVNz2QzdnKA6i;3R(~WY#+oHKzwr�qk^&-NOz!CtVJ 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

  • 7f!e2am{;6E|= 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

    VHE--(i9kLN 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 Q_&XO$WmnJ!nF}ZX1^5rDa{vGU diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/test_utils.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/test_utils.cpython-38.pyc deleted file mode 100644 index 99212177c050cf31df17c1ef2073a3532ada8b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2512 zcmb7GTXP#V6qdB>+a^s*DH#Z*EW@R2nK<+mCCL6II*HT0(7veXy~r7u%+`(iWN6D!L%ASa!pPuLDIWF{DZ;7N z>nmvIKy`*nC!d9pEZO-c8QRG5+~zzdCcJ4*ZFD=Bkn%HW5+NC%Fb1(>G7MJwv3+Bjk> zwpy47pb#-73-fJ!6Y7)DDrIzmo&o7n_RM|8T=v)C!mD3-!bWHxRL|>BRR@G79m>Hq zer9ix5#4k47-u_dNL?^xm&iJN0e9J9T`HF|my*mKf(^O*nDG)XkL`YRr6=?e(avL- zeL|4}y97v3;ni_)Ni&wEyOChg$b zOV#%;+O_8fC9veSGP6^PhDp}SjoZnS%+ze~&hu26(x!|G1Wj9}5>K=v(E$67JP(b0 z2L*a{KqUqNX$kbkKSKBj=G7bsLg(lQ)MfMVrnBCl{{LPQ(1ukLP}$yYaeRz-V=$8! zQCJkGpF0=1tjZur$(uQIP6p76(X9^(_K~I7+5`h^vUze`h44)@?XXDz9|CJ35IZjh z;zN=zz!_}}#b-x!NIPVYbeVLA^jG%KU7JANr^d~qo(PykREB2q612yBz*|WZrDMop ztE-3!mz5#HdSvikTj&sXhnOgjh1A0xfzzC`Ni@t`VVp)vNu-c*8+fPF^puXI4qGzs zNhGc*B^ei6lj|)ItHo0%F1m&=@EAhnWsoOA31%e>14vtiCrp?Lu?Z8L#|dU5OllKW zPQFi*n$s}lDBX;j+$RrI+)5DpoN9t8*Y+$Sd~8s%+NrE_$v@{{}WV BX5jz; diff --git a/env/lib/python3.8/site-packages/astroid/__pycache__/transforms.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/__pycache__/transforms.cpython-38.pyc deleted file mode 100644 index 8f788f00f6bdc39dc165da6993acff59f2c94b88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3458 zcmbVPO>-Pa8Sb8){nSSk#}RQQkiirQE0SG^52TC`xQs(WRn}FO62cZ?G@9<+9cy-G z-Q6oiTeDoGD!6dq#MM6P$Y0=R%#{;=AqOhY+p`~%R}?8mp5C7Rc>Dc$`gvb}wz1J* zcs~65KmDI>F!nF{xcZdv@hiOg9W;Uo944L^@`WKuQx z&jatI=z19T20I#9w3MkAHN7BB62V@>NL<3-vtsTT%u zY&YB=N;9~B_$Mp=&^wLHzzY&@C(uTvk=XHusTju+W5P2K9>#&zcIRmn$DRp}F%~FE zXVAQo+PvqT2Jx}g43)?l|a6-JUtLy*#lsI?HRmA0-g%zd?pLXc(W|Ihcoa7XQ|K z6%bk-24CrDB15~FHsGn^UAW^29~pnjrcUN$>?uF4s@oZ0PW{Ze!=|OI^lSFz{XaNU zcUsQMf*;rP{j8kvbFS`YF8xj`Sq0;D)yXPTo>iW*%sDQpyPQ4yEw0ax483tRfBQO zsv-`^T|!7+3S(`DyPFFses7$Fd3^*JMPXpD2xr>37R@?sZ}^M#Z{k~12w1to8;wNj0{_^$BDo2xNd?7kL?G6}(Jk@+z?2Eh>g+);Z73Www0n>xnH5Q=jLpnC{`$c}}oW8^Auc8NT~bU51k1&Ji1D$HS%d;i4^^C+}-;}p!R_t2S3 zSkaWE-6OH22lU)p>iIbXBpjkQMXS_zsreo?FKJlcrMQ1JQhUF|tX0q@1wZ)q3eE*I z%XtH-C!wqoN<~bQm(6$-<5D36oLUJ~5t z07OVx7suEnO9zoWFVJ3~`s1NY%q)o$?H$<6IV%H}`VND$nS3ws?3MLS2N4n{rFA-D ztZ{%z7uxIbkv5ST8zf?gOjXp6k|3UOa$zrJ=pxb5$sk-yr+Ec#k%_o;ZE(AdrS*Az z;Zb!95qX&{ZmF5;mkj#|%ZmI~oBUuU?5pel-^fqi{w$eGTLyEPUs_A^lpLnW+$b$p z47fdB2w9r&cwvGw`QeHQH|-Ttvdt&kHy_nRfr)<`RKigP^?ei+ejyh9b>Dvm&&_74 zzAw_y_q%T#JbBRB|LF0PPyJ6HeBnQQ@bKeD{{AQ3M+*O!VTv-9)wA#gk(_E$^J8jS z)KGDHrLi1KkfQyXk~>P4n(I*M(%7!mYYjZEq7_Y7Q84nlWxq5<*<{b7xhoRw0k%M@ Q?H1x+;PzZ$$Go1$@BE%GJ?Vep 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 rYd= (3, 8) -if PY38: - # On Python 3.8, typed_ast was merged back into `ast` - _ast_py3 = ast - - -FunctionType = namedtuple("FunctionType", ["argtypes", "returns"]) - - -class ParserModule( - namedtuple( - "ParserModule", - [ - "module", - "unary_op_classes", - "cmp_op_classes", - "bool_op_classes", - "bin_op_classes", - "context_classes", - ], - ) -): - def parse(self, string: str, type_comments=True): - if self.module is _ast_py3: - if PY38: - parse_func = partial(self.module.parse, type_comments=type_comments) - else: - parse_func = partial( - self.module.parse, feature_version=sys.version_info.minor - ) - else: - parse_func = self.module.parse - 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) - - -def get_parser_module(type_comments=True) -> ParserModule: - if not type_comments: - parser_module = ast - else: - parser_module = _ast_py3 - parser_module = parser_module or ast - - unary_op_classes = _unary_operators_from_module(parser_module) - cmp_op_classes = _compare_operators_from_module(parser_module) - bool_op_classes = _bool_operators_from_module(parser_module) - bin_op_classes = _binary_operators_from_module(parser_module) - context_classes = _contexts_from_module(parser_module) - - return ParserModule( - parser_module, - unary_op_classes, - cmp_op_classes, - bool_op_classes, - bin_op_classes, - context_classes, - ) - - -def _unary_operators_from_module(module): - return {module.UAdd: "+", module.USub: "-", module.Not: "not", module.Invert: "~"} - - -def _binary_operators_from_module(module): - binary_operators = { - module.Add: "+", - module.BitAnd: "&", - module.BitOr: "|", - module.BitXor: "^", - module.Div: "/", - module.FloorDiv: "//", - module.MatMult: "@", - module.Mod: "%", - module.Mult: "*", - module.Pow: "**", - module.Sub: "-", - module.LShift: "<<", - module.RShift: ">>", - } - return binary_operators - - -def _bool_operators_from_module(module): - return {module.And: "and", module.Or: "or"} - - -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, - } diff --git a/env/lib/python3.8/site-packages/astroid/arguments.py b/env/lib/python3.8/site-packages/astroid/arguments.py deleted file mode 100644 index 5f4d9092..00000000 --- a/env/lib/python3.8/site-packages/astroid/arguments.py +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright (c) 2015-2016, 2018-2020 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. - - :param callcontext: - An instance of :class:`astroid.context.CallContext`, that holds - the arguments for the call site. - :param argument_context_map: - Additional contexts per node, passed in from :attr:`astroid.context.Context.extra_context` - :param context: - An instance of :class:`astroid.context.Context`. - """ - - def __init__(self, callcontext, argument_context_map=None, context=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, context=context) - self._unpacked_kwargs = self._unpack_keywords(keywords, context=context) - - 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, context=None): - """Get a CallSite object from the given Call node. - - :param context: - An instance of :class:`astroid.context.Context` that will be used - to force a single inference path. - """ - - # Determine the callcontext from the given `context` object if any. - context = context or contextmod.InferenceContext() - callcontext = contextmod.CallContext(call_node.args, call_node.keywords) - return cls(callcontext, context=context) - - 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, context=None): - values = {} - context = context or 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, context=None): - values = [] - context = context or 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 = boundnode.instantiate_class() - 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/env/lib/python3.8/site-packages/astroid/as_string.py b/env/lib/python3.8/site-packages/astroid/as_string.py deleted file mode 100644 index 653411f4..00000000 --- a/env/lib/python3.8/site-packages/astroid/as_string.py +++ /dev/null @@ -1,631 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2010 Daniel Harding -# Copyright (c) 2013-2016, 2018-2020 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, 2019 Łukasz Rogalski -# Copyright (c) 2017 rr- -# Copyright (c) 2018 Serhiy Storchaka -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 brendanator -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2019 Alex Hall -# Copyright (c) 2019 Hugo van Kemenade - -# 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 -""" - -# 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_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_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 "" - args = [n.accept(self) for n in node.bases] - if node._metaclass and not node.has_metaclass_hack(): - args.append("metaclass=" + node._metaclass.accept(self)) - args += [n.accept(self) for n in node.keywords] - args = "(%s)" % ", ".join(args) if args else "" - docs = self._docs_dedent(node.doc) if node.doc else "" - return "\n\n%sclass %s%s:%s\n%s\n" % ( - decorate, - node.name, - args, - 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) - generated = "for %s in %s%s" % ( - node.target.accept(self), - node.iter.accept(self), - ifs, - ) - return "%s%s" % ("async " if node.is_async else "", generated) - - 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 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_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_joinedstr(self, node): - string = "".join( - # Use repr on the string literal parts - # to get proper escapes, e.g. \n, \\, \" - # But strip the quotes off the ends - # (they will always be one character: ' or ") - repr(value.value)[1:-1] - # Literal braces must be doubled to escape them - .replace("{", "{{").replace("}", "}}") - # Each value in values is either a string literal (Const) - # or a FormattedValue - if type(value).__name__ == "Const" else value.accept(self) - for value in node.values - ) - - # Try to find surrounding quotes that don't appear at all in the string. - # Because the formatted values inside {} can't contain backslash (\) - # using a triple quote is sometimes necessary - for quote in ["'", '"', '"""', "'''"]: - if quote not in string: - break - - return "f" + quote + string + quote - - def visit_formattedvalue(self, node): - result = node.value.accept(self) - if node.conversion and node.conversion >= 0: - # e.g. if node.conversion == 114: result += "!r" - result += "!" + chr(node.conversion) - if node.format_spec: - # The format spec is itself a JoinedString, i.e. an f-string - # We strip the f and quotes of the ends - result += ":" + node.format_spec.accept(self)[2:-1] - return "{%s}" % result - - def handle_functiondef(self, node, keyword): - """return a (possibly async) function definition 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%s%s %s(%s)%s%s\n%s" - return def_format % ( - decorate, - keyword, - node.name, - node.args.accept(self), - trailer, - docs, - self._stmt_list(node.body), - ) - - def visit_functiondef(self, node): - """return an astroid.FunctionDef node as string""" - return self.handle_functiondef(node, "def") - - def visit_asyncfunctiondef(self, node): - """return an astroid.AsyncFunction node as string""" - return self.handle_functiondef(node, "async def") - - 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""" - left = self._precedence_parens(node, node.expr) - if left.isdigit(): - left = "(%s)" % left - return "%s.%s" % (left, 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_namedexpr(self, node): - """Return an assignment expression node as string""" - target = node.target.accept(self) - value = node.value.accept(self) - return "%s := %s" % (target, value) - - def visit_nonlocal(self, node): - """return an astroid.Nonlocal node as string""" - return "nonlocal %s" % ", ".join(node.names) - - 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.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_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_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_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) - - def visit_property(self, node): - return node.function.accept(self) - - def visit_evaluatedobject(self, node): - return node.original.accept(self) - - -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) - - -# This sets the default indent to 4 spaces. -to_code = AsStringVisitor(" ") diff --git a/env/lib/python3.8/site-packages/astroid/bases.py b/env/lib/python3.8/site-packages/astroid/bases.py deleted file mode 100644 index 9c743031..00000000 --- a/env/lib/python3.8/site-packages/astroid/bases.py +++ /dev/null @@ -1,548 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2012 FELD Boris -# Copyright (c) 2014-2020 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-2019 hippo91 -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2018 Daniel Colascione -# Copyright (c) 2019 Hugo van Kemenade - -# 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 - -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() - -# TODO: check if needs special treatment -BUILTINS = "builtins" -BOOL_SPECIAL_METHOD = "__bool__" - -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, context=None): - decoratornames = meth.decoratornames(context=context) - if PROPERTIES.intersection(decoratornames): - return True - stripped = { - name.split(".")[-1] for name in 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, context=context) - 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)): - raise exceptions.InferenceError( - message="Cannot infer the same attribute again", - node=self, - context=context, - ) - - # 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 - 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 == "": - if attr.args.arguments and attr.args.arguments[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, context=None): - """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 = context or 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, context=None): - 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): - if self.name == "__new__": - # __new__ acts as a classmethod but the class argument is not implicit. - return 0 - 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 - """ - # pylint: disable=import-outside-toplevel; circular import - 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().infer_call_result(caller, context) - - def bool_value(self, context=None): - 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, context=None): - 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/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-38.pyc deleted file mode 100644 index c8b224c880601f02a0a46f5b2c8e653b9184473b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1105 zcmYjQy^h>A5GE<=XV-V@yTlHX;Hn^v3R^`2!!V2>2mb^qvPBFx0s=uN&hAMoQEQUx z_yBE_b?e&gUFp}zW3Ww?R|pU|Guper6gU!RhBNbhGkSS=IAypVzW=j0mW=&Hhfi0C zhaYj<=O`3Yyk#BFc_(tw1$ofPTy|j|a;9PxDEXG>kqTAxmgO<<%LIaE0urJfhxjT$ zFY$t<$=?`@rJ;|1Ih~*W^z2tZDa~@zfp*r1x>sQRVXYTnKvz(>dhI`dY2oJ^%~M#E zo7T-ML2<5Egl`1Ep5V3`g<}nG#J~ow_&c!`gJ=SK;^dC~!CiP6DWQTZu?+^+#6wWT zE+LN{f69LQb}P|ia>cgc5DZ}v4-(~c2$y^anp=Z>%w9cm2Sadqc*Pcc#}SmAr`*R? zuN}N`eljmRu70d!vf~sW1e| z5GK6QmewL}AFWGd#rePjW_i}F-NhUU^GWHP(U{cFYHeLf#F5H+iHVFq-fLZ5Iw&fN zmPTF@*Cxgcc|t{4s%bh}3o?00A@a$hT*0XLz|5EE{g2Mh`wlV-l>ygl$dZg&n{sqa}Zufb%XUuSK7maQ+`d9S~_|1hIe_t0-uF2QCc64ci!J2Pdi_mX%( ztQPLCFZ}Is8VbTUl1il5FHkUk#3K=j1D^01?g*b5H(#Tr;$**GG%3XWI317h1G~<) z-0^`s>bfuw2Hr@;SEB!(v`vWmXon~IZek@?IJznrJ8cq-fRtZX_&iO#Tx@jZr?tId zf8V&tDH2$pZLkH$bVtIQwegas1KCHJ3Ue0?=7a=syBA-P^WCED`;{%)n&`j5eg{qV z2n9o|2V%+(J_<4YSA^yp)TMl$PJMh$s3F|r(2eC7`kVJ-MGTD>{AUK1wZ#GpXG(1s nz3IH93H_v;v9PhGs6QqD5Sw-J=E67SQ&PLr_F<(x8VJh3&M!0>y&fBVovT}^Kh zA;V>d1PO2(G*nvFJdek9J&B82#(Kv28TAmXZ3 zoGmIYbS&AdmRiMgq2@EYW%)i;ijTyU3B6y>n53H5BC>{Cqge$COhtb~Ka;{w1>XCY}g0Nc$TA<(Y;hHx9|7-Y_6Hgh_$~S4y-QB zLzwC*kQFMCigJ9?>`MF`{jzsOG+7btlv#f@2SssfzXYrV-D272r6ZxIkCSo?LILi;dKkWx5T3@Rr#APok z6LH0b(o|&31hlP>aSv%#8Ml~=%yg(qfz8FJ?-8Xio)AlF2FeZFgXWdNKI zs=I6VW#=ZkMS5cr$e+%41p%Gz3c3p91;{sr4|HpUEegQyw^vT{S6prbe+M+(x6YNj za$65pPWb?QXivTNbS}?#a}UtsFUK$W1ryLf)OHbz4{aA5tzq(ihU<%6EAxjOz;-o!7d?A_&y~5 zJK}}J1xUJ>yz{*+EWZHVeq@3)&Fd^pn+!?&z?e=U>m?I5eUIRrY}klT+JGAzH+M}> zvJqFB$q!zbu))A{RQf+Y5aO;A;?U`ChB0`D2qN$Q1#A_@ Aj{pDw diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_boto3.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_boto3.cpython-38.pyc deleted file mode 100644 index b941330e7324f91e51d572f32e1d4f5d8b9e976c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 933 zcmZ8f!EVz)5Z$$%#BEavA%uj)!3Yku1T|8nQlSbF(iByqtw>uWd|>5xCy5)|o9?bF z8l@-r2d?dr-{3QR<-{*=fmyrI!b&siSwD~8ythZo%Zmip#+PsGgH6bHQ`}q)EM8)$ zEliw*gi~&%G^DuODb1|V%Iwglggc?b8@&0Mgbm)}F78dRE?Pj3U1&h_(qOCu;xEkB zJ4#EDaBnQcM0rCYy&~rzm5y?rz8f#sAUvumJ1HENA+hClqh5jYIP7Pxb9M)#?*AVS~xH<(Zx{rF>!iMHJQ^-^xT?T zBRVI?IPNBy6C`fW)(>TrE99Gbf63KtJuSQxr}5Hc0vm# z7#o3(w3dvmC`gBoJyZD4D}Vt>(1pysr`18ZbOY~O(r_)CsfeRg`F81;u}de$9JYr= z9{*|nl}Hz%KPSOhWDqEbv8~7<7$urXmKWfOZ;BGhRC%klv;7Aa;ts(G{jINwE>GCT;C%b5Lzvc(t|F=J)x zYIe5@5 PW4lYP<4^}hv3~sqBe(lE diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-38.pyc deleted file mode 100644 index 39cbf37582ab9e86ed4b56690a8d52ccce8222dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20676 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 diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_collections.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_collections.cpython-38.pyc deleted file mode 100644 index 1653dac44d8c94858428eb147b0da6dedfba9dee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2531 zcmbVO&2HQ_5SFxSuj(Lakwel;0U?LN3&@s(UIHTg5SC6V6@XXYbk_|wgsI}Wx7zx+Xd z#jn52PrGg5&trVlL+qHt+|)TP-|n%?JT`dc9D8iYw(vb*+iZmIA-J!%zDz6HKVRab?qH{#*DiCl_tLrR=z;0q7+LS=^0%D;Tbxp*0tPd> zNHt4hy=%Jhp`A2L74l1f_iKdb!yzEIV(iCEy2(I??WpSrHK(wS>&4kQ8Hk{nT&T)sXHyXb8{NX$A zAL-*rheX#v@UbMCS?0cQo;#K{`X_E68(KE?H0tY!2f1&(ALtPzlKbibwv z9g}pL!o*M-2BnbwX{j=sz_7YsqfzVXQ^?@t=gtx|&w;aQA6)e9f)bI!Om9NPDNtzv zeL7;X;BE102X(!L3*DGfo7|_Z1hy>N1kOcXn^mpaiO$JEHy#LIDaN(0BO)Oa=THUb zoTdxtGg<;}S5?9q#nos@z>2bQhaxF7)wO;;x!*_|PdZRSOem@ivk_M>+>2cqa&maM zcfT7TLe`T)!Wo#I(;F*0xvoL2r4%&3=t%}dmPvJ!ef7BNgUg3Yb^5R6)Br!H^~_(JKvc1 zpE5SiRwxWE!a!*%_2eK7@Ssi(8a>^EjIjW@I__bRAh3rh%2*RJ%<8fqmRu8;Eo$14 zfeq@eiIX3~**Z0Lk3X4G1yyOY$-Sv!a)ebtn!^4WKFWMx5xHkau3b7VU)ilv){XDW zqWM*S#mADq@jUk&W0SIo7Np6zcnJstyk6+ZH#Ajs4y(PrYrXB%?p~+OeaRNW%ITpr zBgKtY%^i=5fm$l*;e@TGHZCRZQwj4#nH-i0wn%}LxgKOO`tHfmlW)KNp%rC&YcQcM W{D&p{k-5w%)A^o1@NfB_`~JU)B+wh$zeR!tFVE|%k+ByMc4wY#YZXYL%i zwntur$MBU?UV#hDI-yvEk#=_Xzw?_}d*^+vRwZcNuiw3eLC6oaDVl|wmpH^zbd*pn zBIC`hjWrktf1WP zvtQpRDqRO%ql4p7$N3M}YL*saGq@y8ce=a)qy7chLt638nx3fFV=tn3TPSx7T0#lHsM2ruEw?el;_ziFuk{dS)CvLjJ2TNK4l!=w z&p^1_QtpKNVY2aFz*ng}N>^D8GkcQziI_4T@2MVAHzAs->A!ddS7R#=cFLI{R)U)- zWqVjxU;}w!GG&>0e${%C$7T;X%t9f7doiQS2t4>GA)&yt@}M{Dy*a)3`=Oha>gTNT VY!m)MHFDm>6|JIIbaPX z;ye5`pW$m3%z8J$IGFWkJHG_uUKPCWSHTZEv)!uqVW)?y5FGCPjhsPtY2Nm;g9OK4 zV-&7}_q|!~gW>OI)89S{f@cT#unCg|A2AK0IQZt^lhmS;>@)$J zE|^TX1!PL6OjoP>WN6Hds7Ruq;-k%~WQw&}f;>Hc~nns|;0Id!-oI`=mOv z7IiWl*{g-htyMImNH~#Z!c&NIdk-rLokV3JY`?egaV3?0lzt*ECTWrpI?{r5kv1H$ zI-@LQXP;Ro&KZC@WRQ_cyBHZDV*CVh#wj}ZoR~6L5Hju}YD6TIjJpK4tCSR0{>?I% zg3&k#)rHP*2u0J58IEMdoljJ_Zwr_9`8c5RNtkZxxg7gRl$%Id8)Au3I=zvxDlUr+#Rv!G!X&K_}| zP{#*}!!Z())^Ex*E%;ObxamyQDOH@=4QM=2xu9*L@*+_gt*RX7N}@^%Y7r~qrxpXD z1xC$9G1DUl%ca{z$W-8faQL8fS`e7y5x9v1?q?48mP8@wWD2;SDsWm9oQ4J=?HO!h z3T}GAYfCTT;AI@Vl!G^rz!?zWO*Pn77U0zdc!dGm3IVoO0-|o?V!u1pfry`U@P{sF zKj(hZp#&^k+IWBm8?DG~Tpm-3h3%FsBx4Gt?EJAZ8HY&}LDvl}AQkWWu|*Wqoq;U^ zk+TV)o2?rTS8O3VLt2hfO8bt1w(yh4Qx!9*y zQHJj9Ff!nnsDUpj`4uIxHXOjoGM0hE0THbOtP7XJl>x2{ObF(wJH(9Ph3i=9J6~?g zNVzQ|r=$+rOW7pCLEhE<|5(|Da|7`U)>X>}GS%o}DIQ>W34ILTh7)IrgPe^L>qOmf zT?lF4P|dacu)lsfZC3SiK3nhIP3xxmJ*ao_8sEPDxe2eAw^i6wmvyyTE~@ZqzM9n4 z-LeVq7xVCLdbzr;Zl{YEO;x|G>abe84R7YJ!@GB@>*eD3=vCOvSJeyT`*C_zHQ|G* z@O3?%FE;PVSjA_mOO| z^`~`pHE&i`J-J=Z?r*9|_0y_a%&L0*6t5o`Gu?T$`7(ch*85*?*uOP@VOmA|JNrKe GNB;q$!txjZ diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dataclasses.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dataclasses.cpython-38.pyc deleted file mode 100644 index 50df087271f3ebf3bb8372cb5b7ea7884dd7a1ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1305 zcmZ8h!H(ND5G5&Dk{$1+-L^r|0I7~~fmnyOKu`oljNNT}Xg7epxfm!ES{&Q*%A}X1 zcVWXmZLU4{njHHZ{S01v>Ms-s(xL732B9z`ayT=Z;d|7}gM$Xa@$}EXa}^Qtk6(N^ zYPfigVtzp-NS_EQSVj93-$6yEtj{QcK!i86A3`{!q9&r(v|kgkNM4hE1nf-=bdo>> zwYLE!g7rwNzWk=qF;=Tmq+_Kn(xK9+9YZR(L8Y(h`S?~m8avK6zzB)nnz z@rq4qYh1sH-jWr)i1g96^vfe3)e4p;U9fX4({nwCv>c{96;LS6Er?Vq0qK|--2f6$EG`ZwcO!C>Cfm`$)%q{#y^a1w&-(@ydQ^*Vy8my9#jY^wqm?@LZWtq)* zfoM#*d}2UffzCi)Wr#;MTiCIZ-?pD-rnK+`{VwcrTDqc^O#+l~ z$ZnW(GS*B^KH@tnq3RSMNyKF{T_z7wz6Lvdn|4{o%Q2 zo7%-M<%Lw&Qh(}WkNno*EuV7lZjdv`5iCFzyfUqt_J09)4=)~O&pn?u8TFUmoanLH z+B|nQ1kxTcWY}%rxz$`6yv5V6aKk)8MS=!BqAX0_CoFo$Y6$}CANDS)9a8-@dbH{; z&U2xPJl}Mv{iSvFp;k+fco_W$C!O=o@vog;@3fbnoF2dEcFtdPdmC14GPolRqtaN= vcNMtg*#ALJV7M*yqoR{%QzhmV{21WJ%;%`WFrm#L37XC10ai#DVekJ3FQsj< diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-38.pyc deleted file mode 100644 index 854e80f53771dae6726741630214737b3fe81a9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 707 zcmYjPy>8S%5cb->vxzPwLKKL~ba9m27Bo==hyx)it^m=vS@~|~?pCpPt=YYVTpQkj zHk7;ukKvYzSD*>A_8nxb9q)|3{pR=c{{CJ-a`x?~coqf0FK^tJn2gtStXDE90?A}p zv4YV*s=_)dqB<^O=KXOssE5Un?gKge8Wah{5Xl6Rn}~ejryx%^Pbb!)Q8HT@b78ZE z!AzD8)=pKwDMB#K!#4RanNHrn``A7~SSsrPMQ!A|0s&tfXbG6J_TiT3&01CDnfu50 zWkAMTI`%Os7dUpqZbKK{#*%%fkCF+e8?%>@sJb!ex;&h!q4P;tWKD?{j=YO_h?zPy>VccA|k9LM|SZYgSst+j-+bs)AS+e8Ry=0f0*0By33)|HL4WkGweb&b2?0sFRiy8lJ@w+9}czUUX= Rm2XCuL>#8!Asa>M=r7KX!3zKY diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-38.pyc deleted file mode 100644 index 75ace5280e14f509a8deabb1526a79359f0ac6c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1587 zcmbVM&5j&35VqaF^S4AffXD^8#SG_XQpR++_Sc4 zqeY(6g2*MgaNxpW_c#&$M3y4}bY1 z9ma(GiJR+>51UV5=phJBI4#Mjndykudp2U6aqkB*^0?0fn0-NK0jE6tk=-FYIu6vA zg3ZE<2xKh$OGd%ZA?e2(@JWWbhtu}y!W_ato&Fufb21|<4-%FHJSOLK6mZFu3=Cq5vHt&b;{loIQWi49-URcwOiga_wL{bmCg(M5Pk z9+M~ckJzfUYTLGwCbDf4&syh9O9L7k&pI~d;R|oou^k)P);>9rpzVUs=p}lOA*yJ& z_FPyNQpn1+^Qug%@mLGv!bPTpG&zN+t{w&p4EH7seH%nUEP1lKqLvy6-O_XRGduAQ z$(pRGizdQk#;7%OY;fNN;4qtm-j@{@3jO>glW8>PjREBRpXFwun(_rUHrn+Tm`+Ni4F$y1dTvXSW+bcLMg z!Q#xd_j!?*16$n zy=yqD*{g|r8w}A{e+Yumuzq*w9`)&M+NL{n7hXmg@dYBQ6HesZQZ;F>ro52t#4>3#OhZ_p?fPeDw7(oO`E&Hb7T50oa=W$5MXo% zIQ4-?A9!T-3K`v{>LWPcU?hFEL8Ke>4bbnvOM;Lz4}p`A5USz5?(<)W`1 z4Ih2++1GAQiAkXil=44-6sGkW;Mb_*{dvWgr8vOEY3!Yt#w_;YTXAnM2mv2^^*3cY BfR6wG diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_functools.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_functools.cpython-38.pyc deleted file mode 100644 index 6b3ca9cfaa11c877aa3f9b61f95bfa8a97afa7d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4683 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 a!~gaFEC0$l>vggwvQnlF}?77&cR zpMLd!w-NeHFXo2@izo1x2S6yII6_`NV-II*;t__93`&kI&!h%5&yZ&^a$aKOs7x(p z%?u27pQC!|0(_vuI=L`lz9<3dXvyW!0*C==tvmxl@f1<=BU0!bYtPi8C0eF-uQWk3 zGR2CBZ)jyo=)%;Cgu!dlyPKY(B&6Iuj##W^Ly0A^i8^Q zW`ow6p%2h^c!sBzDxH@n)=WqJ*5TMb38Eou)oQ`d7@-9RMkflSbndV7V8H5fJ#HVd zj;cS-bdEz=*YW+3hsyWYC5yTZfXcAP12q(YuRnGYu%AQIu*amzuvcCjM=-#1u+7!= zd5cb*jBdc|9p`)x6B;O1#E~84`u=@(dTR)^TH)|XBI1MzHJaN%C*g)riVTTctlLrC zIre2ZzRAbtEyj7!|84CV1G?jxvL9@EC7{jbc0TXyrh2`#x1G&9o6YerkglNBuGJdO zgN8G=Lu+@t;T*G3u9HEea!x;p`2qQnG0%0~fX74C+5|@|QGLxsEa+wtw;nYd9#iJW z-L7OxFaJF`z`URxWJwY9pDn)<1yrTk5#m8+75rj{BqJWY*H zzuW>G*?8pH{Xq7+L*5Y;*z+Y$ZN&yj1f}>Ay&Aavc)(oAI#A;=XKoLAgnuvq-yVr9bS7co)!KxyUADz>p&;^k-A70!bI)eq8fD8P%0?cK}?4c^Vz9loHCJ?KY4oi^y3dd%j3<0&PW!ty`RGm^rukjZET`{3x>V@ EH{eep-~a#s diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_http.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_http.cpython-38.pyc deleted file mode 100644 index 95ce77e080237871d63d7daf9897c5e805207131..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10524 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 RQI|Nx`{gn`QHOdze*=JtI+6eY diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-38.pyc deleted file mode 100644 index f9dd0157442c4b14fce8ea582c8b11ec51ccc3f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 741 zcmb_ay^a$x5Vm*ocdN^B5)I{+w^A-Hpg18w{=I$9VibRDuYq zh^8ggNtw`y6P4;-*+V-Oy$_`9LjqLvp?{U4Z}5^7!|#|$iliMrpUr2_p1x@BI9N#^ zz*X9cMnMJd0vG|VpzYDj2WO=?Z=^y`9dmCA_DG)K@kgiv3G|A7N(B8(@ug&b`6J6} z#l6qZoqg-Uo!G@|s6%l-%TWX@bGrd^;z2DZdE?Y17d-HXb8BFd2dTj}VTbk^G0Q<{ zoXKO%UsWn&x6;e-pQ&;&xnusy)Q9NwcaJac*CT8^oKa zep5YT(HeWSX*;s9w;;A~T$)Z-8tOGS@)D+-i}v<4s)FOjFRjyK?8L`*2p!Snmm8r~9$W{`i$Ocw r7vAx4anJ3oy=%H-1+L>8bN}$`tYHivJ?Q?^qXR^{*N*97Iy(LhYx&C> diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-38.pyc deleted file mode 100644 index 47f966e0c72b224fbef1b64b855e7364c036bfbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2559 zcmZ`*UvJz*5a0EmyX!Rtgb<_^50)VG4qfja`chR1BK-pbHBo7xKvZNo_FT>vpY80f z(_G{rq4FJgL&+mAdh<~+PQVs3G8z&emtD!c)FYH)K=GWTd`^Pl_7pbi>~K(&d&|R+BwUu zb#^#Ce39eY{r2|BwCi9Si)7}^vPgxgNPLhojQ58#FZT99NGF`7iBQhYJodLro>mHA z>{N8Ge_yj`EdeSMaTDF^YvIXH|G$@?#0rkpVyj0m_RyM#C3oOF@FY~kVr!B+8_q>! zwbLHLQP$9^1VtN-Ce6YkOu=2j@!I+;Mcb1~Bw9*U$(Ny;6x|RVh%{o0>z`$@PoaaB7S|snSsZMEnj}HL zRkUVFkVUjv52EQ@!F0%f~Mw4U)BMCnGIEi7jA1YTsn#fTW zhojW<)dcX??nn?vAVv@$jiPXGl+JO#`0nuDNTRKG5O;tVD@WClM|;8x`gCLz3 zx0ac%5?(CFiJ09$vt$oD#w~9AYjt(sHuzio9sIh+3V)k-xnXqpin+p9xL8H(g&ZPf z6F;3pl7+Pzn?M;Jm$V;w zQaan-3?%voddc1teANi+6y;6mbGn(!FpMw9b;B5M#_dUn#sf#qQ}FSE2adkYfrEi_ zu<^CXps_q<4#9`+0*(Q^m}-j&L9ImTr4XXWT28y~gVGx>EncN%L;Hf3th6d4my{b? zSMKRj7>eq|OS;v@x7TEEO$?kh(Z9Xcqmz|Z4qZ1!ueHG^?pRlYTbo|A^u~4NT z)Vzo1C8+9`w?i)2q#)6Ilzx|Rm{HhNjKYM~fb3v{-wOkh#2zD_4(@7%8 zfY(bc3u`T`sX<7^=>ojw*0=}gmJq}RRK=??PbtSXbczjWUJIg7(#dG3c|qtCkA|A} zoH7cTdaSwnE|IIpnp-C-O6qwnbzO8OU_7EU@@9L1r(^5B?whD%O4HY%k3F$3?>p3& z!9)Q^0i|numClsgp%;ZGAU3wK3J)COkd7voqFNd! z+SF0)Z*=b=S$uG*CNEy=*TwlR0wpa|7H4r2XD6%6rE#HGytyRlw+mCwWoZb#fVy_; zRf<&s`*@w`;_?M^@v($B08zBJHn%rFfBdXru(n@Y-B~Z;pU}DF``C5#%h36#bJyY) LGZ?-h=3@3Ac&phD diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-38.pyc deleted file mode 100644 index a9895f1fe5b014915a4335c33c03d09c61ae06df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11690 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 diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_nose.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_nose.cpython-38.pyc deleted file mode 100644 index cc2ddfcad27f5176a2c5318ac84bc7c96ea98382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2094 zcmaJ?Pmj|^6rZsj$LsuA*e+e5rAjX?79vqqsY2Bjby*gQ1bcwef+@0`%xu<)V|!;N zONpEltA2&vs^rMm=*O6APd)e63w>|Aq_79ZdNc3MpO-hk`MsCNt(H%q-T3{_=(R`4 zUueABTrj=|k-tI5NJtoER!T!^Mk}<;Xot2LozUj?sJ3vSuPFFt)h8XyYl?>xVoa z%g#YAI$17xCr$by7B9PhLy%;DR=@ge=X&@&7+7eZHq;%ET@ZN=x{@x;ZB9r@mgv{s zA5fTo+fcVb9)ZYB=ol@@f-E73OJqTpWDAzykfxEqy@93Op~$C&)U`B!!9_qdoxCOj zG5mMbJIp7%C;32dm1n#+OjIOzk;~pROL|2-P=|aHXV)bc$6WMycHDz&^@^A3Fweg3 z-ss6h@$0Z}91pqd#ZrkpVLiBbl2v_#Sage*+S^X!NuR|xG3tLn$ZRVrcyXhB5s1bqOqYKScG$4tsUKv4jZ zvKGLLC46%-+f+_jL04OnS9DH)CfP-YD0fsJ`(m3C{GJkKKO#@?ZM-G9O`boTTctHx zTlmabQcC!r|egZGJ!rZYX?y&mVwWB-u3xPMgc9*M8 zoOJ+I5i4L)e$YV(BuuhSKc7NB;Q&69-Pu#W11*^pxlkQ=FQvFtzL^}Pv6P)3!M^%- zp^MgTEP3#)*@9;a*kz2k^If$&Fs7#QzII`e3ndWUuu&O%N7FbBTa^)Uv}DlIUUcj6 zz5BQK9_l7AAjyVNf10FBdy4<6UWmBRF5`@63LX?@bS=paxX|@ezUcNnw0Sn*dqU)} zaC%44fZx`>RIyOTM>eHmN^#;CnJ^T zsf-S$*+3OwPD&RKZtae*(Tf7`qa2CZXO; zzJi?+V<5Cm#pf`-mj{^Zs|cTffq8&AFbD24dkAqV%fx&cVzz+2bYYj)k^*b(5||5- zUxYkyE|HNlcNEl8;5D7sN~f$vAf*%4OT1Zac5QbmRX*vgVlxF1%7`h7T?2Zjda&-S z8AWlLMiH>@+4IoO#}U-(qe$0J=L1iyL%0GfqX8aBSrj~D+AU(>ixL-LMLYKs38XrX z(&r9K1BzJXXxWJ@HZJ|m7e!Ue4x(aeC1t^fRE!OPNUVGz5!3B z`Vz~hp4A3!_znnl;S*oN>TJW*J#*de>G}6qgT)y$YZqPN-yLuSiuo98zO_H||34m3 zlLlD0vom1|tZw%~#2R*J1?LexmJgyxTY`)8xL{CPKh3tT$xTeZw@Q1bs@u0PX>sAf z&i>Bby@v*TT_5C=B1yT)J@X2NVdk3pqToXSpNpt^(+JWV-Upm)tX5XAY4?H2)OT)y r)D)(kd)t+Vn|KTP1$2((0k|k_d&BWAdo^zZQWIc<)U;irxo`dh4?7VV diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-38.pyc deleted file mode 100644 index 76eda8eb85dd57a4167825b7a99a6e0f95f1f46c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 652 zcmZuv!H&}~5Vf6jTUIPb#4*Q4>c*A0tPmh7ggDUyh)WT&yz#U(ZR}|5teT4B{=;5( zkNgIokt-*Dfy?3~MO1>3{4`G<%{;&H$Fs9j65`_KyC@hTKU#7egFs$|;Ag{x5txQjDsiJo@OknfdU!gh3HA*7Ndi-fRNv5CEt|(>AQ1;Jj z2Bky?-w4J*UkAUw^0h61JIF()poXus7YL0EXiV8X zw(0)y|Cf^vnxPQN=0afj9i%I6o*=BW^MIn?oq(MOqX3)XyV-p9_RaghZuD9Ei<;5% XzWn7dF!v}x%tq1ZK}=)92)q9ch-JA! diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-38.pyc deleted file mode 100644 index 5bbf24d4e6a0c7bb6c461a9f625d70157aba1ea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1046 zcmbtT&2G~`5VjpBw$ldE9^k^k$3{xy@F!J>AcC3#ho(|nE{1C5cqhqHd)Mr)D^dxb zfg2YN$&uIKG4{%dR{$ZgcG9ZcDs?2!{&;u3Z)d)F(`eKUZ989opf9#z{45q%&C`qL z`V(9`Y=j0jv6YyiS&mj{>9LYjQaiNMYFIT5Y~w1fVdq;VtU+z=ER0>_n%{=Cg<1Z!!ChF3ifMe(d5Z4x>L{@>pD zCk$ghAyi~h3|m4*T(*57S=KH9dyl(qA1KZkp|W?(b7=bzyH_M$}SC6==cdP7F_ zJo-pPuiJW3_pg{fpL4pRPjSR~G~0Ts<91J4=d%)?O|B1LJh^wj+tC4T2F(iS39$6~ z*f#=fRYLb7(R#LebLd@CXf>6C5N0t#$}3CESR#}YEv29~Mm!>PRlZ!3L~u)&oL96{ zclHOzuMT#P(D4C!F+i_}dxOKn!LF(j38`4dLo`Yubc@hP@K`ySt~QC1l`w$DfG(t^ zoc;c=|8j7sHaSd)t~f`MM^tDjrpoI}$;l{}pcJvQc!!CH1l^I@wIQPnWIn%+YMbJ?(7EHC?l5TZR3pc};WOteLjntN;B6-OWtO diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-38.pyc deleted file mode 100644 index 6d007f8201aa038e7e7b6019ea438aa525589322..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3258 zcmcgu%WoS+7~kFa6(>&9^vOeFB@VGAH%`T+LKvDhDIioMr2&a8WwqY<98bMFV`gR( z+r4t*4i^r|krVt4oVjt^D<}R1BvihcT_;YPhNh|*X~*;M_xgR0`M#*tsuqr0KmO+b za>26x)SKCH1vj_xlfUCcEYBh~aU$EZ&9CD*_&XQP#Rabr7rmlwkpd}xXL%)X4$9y> zu8-MuofqgqJa>>*o`?!B3SziA+S0PC%qPF0zaYy@C}6@ zL)-f>}KzgArw@4AHckPR^9_7WB<%9(Tt z^e6-3Qsy3Owl*9a61>C<2BID`-EQN3bEtU

    EoJQhO?)sxf^@wzjaCI(9 z%~}t{q8wx(ro~|(B>ZfN653^^zn`@FJcgEp5cS{;TDw&F0)||+5=L9YAXI&b19n4# z*aOi5w%3Yiw>2EAK4p7QNzzWaU5fjV+0RHs1G z9pxOy=f+|C2#31t2SfBn217660s1n>;qL0o*q&$4WJmMtQWo-rsrsnt?gQQJtEt)O z?g-ef>YvZ)-y5!pB*ECvICo)}V&*D9Sb>pzwGS|e1374~-qd4#9Rse^?m@v{{pV zt&zq?QKSr{k3|s`(fQDHvDRg&i%R141PR)!ETDTDvKf`9GEbM2RiEM2(H8WbtS5vF286@llikbY*)AQAp{3??nf<1_Q z3|Sb}ai*cJ7kRP!kNQ?W)%s>*V#?+O1edR^Y&I^ZMe|6cbNIA*)#Jy>TbOxB(xOSb zv}o?V%CydUi&>y&wb85PyQ~~}m1#}zN?C4uE6?YoH-D5aUO5k5Z~58y^D0xPd9@P} z;8l

    D3Z8gL_&uST!!CW#1<}^!;?+G;o|pQWUViNH3b!C2v|1Me*FhbD^6;(}ASd z1=f41u#3#PP9H}2wqjF}mhW$LHa_0kPOskI+WF-3%?JL@=l-27|I^OBt?lit&9sQk zQY_Pj7_faJJ_}+<7pEPhj}VSZIm~vz(Vk+e@Iu3Bp>xi>HLPmLe@px02 Tm+eKnggsituKrUfPFMc|$42!K diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-38.pyc deleted file mode 100644 index 7fb3427fce9378c6a7b28bdb391157cff76b8ba4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1290 zcmcIj&2H345bpMP{*p;H7{2a_S3p8+wH-o`IPSLOa#gvy{Pp)$zg$~eA-L|o|C`O4g#6=z z%d3mQ&-j>kXgG-or`$_vM60(KdH8Omjm(eytQj>a;XZHvNum~bi#B*~JG=$0WdrkV z-VrqFLU*yUB>Uveo!`A^HR=IftU(icOD|e?^@|_SZs6`Ku)d_#S07fFp6l_)6Yjkr z{qEUd&sePl4`xaon_#MRAd4)Y4-=(fh%RW61exMR3d0YGoQ(Tk`D5y;St^c!Rpl&$ zYy!I66mkmsn_S{HU0w|g9^hjfUzRM8fF(sR-Z*|m30VnnT@SdJVkeL`m=-dzLP-;F zm$bjUr*71CM`_>@1)$d=l#SZ^N*J+Wa6`>C6RA6utrv+mDPjEX< zQMYznt6etpSR43@=oV^FnUAO8Ol1%nNRS0QV|XMi(~v6@7E*+HoY)y;vAk(OpMVZQ zo`k8Gg!$agl)OE>8yaEZCe|ItM_|J9UxgDL3t8Lqxp1T9+;aiTYxM|SPBW`xX>b~| zbvG#vC80j`KI;y8XPecIZ)P;|oi1n3o$$`vHnTYYK79|i`a6}Hjup4QEBk9F`g_{#Rv zz46|!ql4(`)6wChXZtVM;WPHjh&>)Z9332t_RA)+nVE7m1LT)88D|jnzT5?7bW*la zL@VMns&5_01lX5?a`WQP7gUzrJ!`d?6c)<0>Y`R#tjNEPLG88i0A=T1jrqQd%ndZY e*P$J{(dhJi>JyK6pZ!*CH)xNxP@oQ7`SdSo5`<*{ diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-38.pyc deleted file mode 100644 index e64fbd59d5a9c803e38ef81e2b764d2c0d202cf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7754 zcmb7J&2Aev5MIf4Vgv}#TYD(bEqbsVD3!@wWGC7EBY4w>*1H{Oz1>arp#6TQ6(sFf!Qs7| zljqtf$&+v-n`P4RuQ>Jw|1VJ?& z*?$YMIeccTh#$5NqlgP`qNt-G9dyG9OABZ~2u3wWufxmmr4%r0Jgez54bIAh8Ro7e zC7iW`lnwP=wZ>V=Gd6Tr8pt%iad#~GQ-kB>(pMxrb5<%~sk8FVUU44rWZvz}&NN6Y zP3`y`J_{9?LW!^tT;NP#{d7Je7AdB_NHxsZ^%h_*{J~l(qJ9-1|z0|FL^b`THzUz^o27K505X^u>>O0Wnm_0@2=%%-T zYVcK%7?UUVWbW@IGhn`E%eSx@WRM2Z_w(i6SK^3RR$QpyY8 zQC4gMzU!VgZBMNf0-pshvM=( zmg+jnwdHjuGYie=Oz1kX+<8Kq?E=o`@rWsBB_3H~cdd;L+(#+vG@PtQOqcd@BDl87 zLxOXsh}{O@x?k`V&k=WU63p<4`%qX%4NeYYE)r*D28P{v6c#LV_f3^IXq?ADeG+9Ji9NPu*7m?(G8IlRcE?a2b*`oC=xKNQWERYjfK@Obi$@FOM#Ak zUP+ECfN{q3`10U{p5tRYRgPrJk&nKlB*(gCRs);{skzpGhKz$0t~nmnJ5?$MmC7+Q z(?Im4Oe1$Sj&UEHk@dh`jc~HvBANa z8)4N-To@Q4rX0tH=4;HfCIx2|Oh8CHH!y=a##K*mAvOot1T-bZMBz0`I+I~lO7xi$KBCD$!r8=dJ0oM zHZ)l83hGHfmRuHZpt5dg4fVGo+wUK3q{kz$se5+QeoD%8UFX*nr zjt2U>3^J*v6mVO^(SCW3WV>&c6wGEIfyQ|DUmp{MviXsv#fdC%8%AP1h^HkuwqmZK zr&0`88eN>0+^BN7VO>|+C0fH$qcdpAaQ4)4oAqKjRzzDSCQagqrGuJua%LN&)}$(a zo|Lj-iJC1C;$=d;cM|H2b~46Y-6S|kY z-OHKM@K>OA@m|rs{`;*rk{R?g#JE*swA&lv1t2E2r0!vty&Qvt5oAm})}SV!dLSmf zl=pl2)QqHfa&+F)cp7?)xG@`o?p0m&`igN;z9Wo8@@Yhupj2#LOx}L(sEcf1fj6kx zL%IjOhp%97x7GfjsCe_SZMJ%^dboFcKZ+6=N0DkH(4ucYQ82{h1Nx8h+BJe}Olsq; x((U~h&tE?O{@Wkt1}RH)1AM#xWeNXkAOGo(@U`3C-`W2?$ah=2K|5%F_#fC6JYE0* diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_umath.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_core_umath.cpython-38.pyc deleted file mode 100644 index 5db1de3f99f4c5d86a3c4df8b2deeb73e3103bf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4396 zcmcgwO>g5w7Y+)MP1?BRncmjf5tFaQl-(QdC?ely0wj8*QfBhX_yyG~3 zm>;v(8vJ+yA6>%S#@tusl0)6EoZ9;J?wL-M z

    $J>}upog+v;~!-gjnYorlLIw+Df4O!z)(CnOh=03Sf@Wohu1|R({+-T{AlQ=KI z_Lcj+L(4yxUX{R3<^1|HnI@;_Qm{JecbH%fcbJ0P(%Mq5=Xgpb!=40+I>0fHonSB;Ga0DH91# zhM;#jgXV!CNvha{W2)mxmc)o99Z9DTP5u<4smH2bsOyNp-+=3JDQ3$uDeOXm6$4{p z+)aWKrO2@Q^OCwFXgok4A(IFPO45VuV`kc-8=wlZM8 z+_ophm6ezV0Am&oU2K@Lprr^c6lR0CWg|xWg;bxki_76F(0o_aj8R@Mu6^@zEe?xA zJ^Z^G#^Rw2Y_$C)wr?eiBL=k`zyu3fTrN1yEb;3$GQpr+yjL7qEH$?>K*3s2xWWJx z^LVTzI9klYMR5e?RbD7*h;42Yw)DAX82@bq7bG@8rU}N%RJX|cuyc)`Ta5^hC19a%g zVmgDQ&vnYYdOwsT!LjT!ODMo36<+0uACW<^AAU3szzc3zV+a%j474~Hc$N%whVlGB z&ztTr(gV1$0Cw~0L*^$~cep<{REs>Yh7>juz!IS=j7(VOz-__E7~QOm zJ%K=5&rW!(jSaoPqtuc%Xa_rkV1tDC*0KXo;}!kAqO%o?2%O7py`^~2Sy@5YE)zvO zON{}f*vb*Al`c0Yr`K9}v;q6A*{?@yF;SY0)?vejr5dxw-9zAg!vZjL=_wiV?STKgiiXG`948xK-TE^5zfDI(Xr@j(hVrO!_8a diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_ndarray.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_ndarray.cpython-38.pyc deleted file mode 100644 index 3597d12123ff3854c75502ff44a3369dcbb1b65d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8391 zcmcIp&5zs06(=RxD=*>(XoCPL5P&g|XcfpSZ+Z!gDu^2-JrvnPl3q3lh!OcH&5E3% zXNKBc!$uDEwTGU1wU7Nbdg|YxYfk+a3KZxYYKG*BtJMd$0`x)6%$wi)ocHGa`QgJu z2VbB6{h$83A34r1`l0%|j}KqsTmAt*Lg&m0-LMtAXKw!8I%|aoVLR-+cF)@3z3~2P z=d1&*^LuaZbZKe;~%_{r-@#pl#h&wgtdc##wOPe zheVO}gL>`S(I_U9^@MR$tzAkJGQmNX9vfvI{rF_yJ^86$XO1dJBz>_S1{+_gTNq>^ zP1fQNK;kWNs)(#qn2mq5aIBthp1Un}^d8&M2yHiy!AmgwMlA;Ue)A&+K;K*`dR;}v7YX1JGI9JSzvN?$Qw5{NA(Fk42FB+{E%@riGaU%!{17+#h z``OuLGcm@E;zJC~2%t2PlNA$b?g+6pu)QRd5Y^BT8v0?w-B}|IF__dew2gNbR#hr? zn`J4tIl->$tTXSnPC#m-NVyPmzoXTY`kJ?wQ@7y>tBch`ux5zs&q4%KQ@~9C8^)45 z2qldo35jD*79MO;#U zp3z{Yhxeo{bt!8|=f#PI*!vSw42V>eO-8+pNfH76gBH(cBV8=uDAou0&#h&jm!uaY zH5*cv#w36p?JK~G4{0&u0}VhT>cVU>^24Yn2$j&=8d(riiwdp7H~<=)y@D{*x2MOG zRDhI*Q>?wh+)#{pm|KwDsj~B&;tn|2c{U+xDX$%trPhg;7Tf!32U+4(fZ(BFy%Ji= z>bKO__K>nfX2~5B4Jny$Mr;@?uBCD(KEeB`{KsdbldWNf+A$-JFm$Ep8uQ_LfwttS449Y)_ez;|=DVX4Wt<8CafF zxg+92swVj(OaaO;Ajt@*&SOyB7nlQH-E`@qo`z!k$YlmtY< z6oO@DQG%)qgJ-OWFc9E0#SL^11kJI-6d8Dx^@rW)Q?1;sSI>zs z04w^tDaUPW*>egPW~(awyuGS5vJrCMT^#8C4_vB#dvSneoo*p7-oa;-v+^0%OpAMY zYXHYP`cdfC@#4TVBLCrtEz*c1}N9!n5- z%RB@&AI5Y%Os~|Gv)>(mK9m^L9^>d+Os4IjAr*}U}cqTBsGJ}B&PEBCzhmll5yd)@8Oo#~Ex>r@=zXuq>K zq!Qa>im(8LUb%SiOrh0|GX;w-CdY!21p2PfyXMkZemu}qKk%{PGn0NyXK)?p-*8yw zZFpDw3V-+A)Bc0Sf$xVr@cqSuC}V-*JeK*MIUo7F#lg4FPM`hp>+cr77BE2{1L32x znACnL-qD*r%;f@z*H<*HK+>ubIj-*SG0n(g_(DI)_wb|B>bl+b;m=OH+qv&{+^*aD G@BaXioBJRD diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-38.pyc deleted file mode 100644 index dfdd0cfe896496ea136d68fc1dbe970a1fac4e8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3260 zcmbtXy>8q_5GHviOEBUzY0?B>XI?-ZEu;~QoDm@~Tt!8G8a2d{J0v&SA7*!X(y7in zxV1}{d4)Vc9^hJ6euXs7EO|Jcg5@(4=+MGq0`@kiwMFu69|8u(gTRzPQrjjKLxW#H^*njYQ<>W zD0OM#O6gd3qFv23kyMGfuxhPgR^IB%MzIo{BU>+0bfV>?gvHOg1GLq{H_9|C8xA%hylr;1?Y9}O zTa25uE-a=b92O_@XFIm+m#)xL%y1ghiULM;>%xAqng~G>(~uUu8-HpIN`OUw6aOsM zU~^-Mh2$R7I#B>mxGERV`aq11NwaD}-gm(?fV-Kk4cNAbCt#otD7E(cany{XR+KD zPx;f?^PXoMJ2BBJZ3pVxzTEKAz=x6&t;s4$PSTUvY)eq?Jn3tg5;@uiHE3j~|1;Q)x^!E}~t$?^V`dH`PI4iPt zWg8{GnV)8cSvbahm!t-hZH~$cO_&_!ya%1!p$k^~(1g$1)%vUdc%Qo#-MAd$he2Q- z;S_|^F#4$7E{KKgdp{^Af<=5w5;(b44SbQ(^BD2P7(1Bb~j`2YX_ diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_utils.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_numpy_utils.cpython-38.pyc deleted file mode 100644 index d6001a386db1597dcd631c0a8c3bfa86f4fbacf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1885 zcmbtVF>l;96ecO1PL?le;RbaI6sX{#h=AtQx=UcVMv53Ny4+B^%OQa(OFSR%BvB@L ziEW%Gd+pGvO9p%F-{@cHrnOW4LeV6Bk2*JwgBAr!fE4*2`S|gBAF1ze-3kbl2S5Ls z>~;zH9S7Ho3xkJH^)@s)8Iqjlte``hFXv9~p3@=YbmB~0-pM=9S?=ZCb9dYd!%7NZeYyfWd;h(Z{_bvTkLG-DoCv$8%8_f;w?{Q~wRgUrFt zqF^8EBdGdAXbicab8<;f>6}j3oaOXK3cIjDM4N6VE5naW8zn{F^kA&g%p{e} zdD9UUAOXLlRo1v@Qw*a1LX;1mKMv!uEP1SXrnr$6j}L@N6tAU@XO)O+2sGwpTHV)N zJ>@Fq)zi2T`*D42#NXx0GeKxT6(%fV3bI8S4`9tyl~Hsq3QojoDS8NIQXN+H->#$Z zD;V|*kOi>G?|t!ExE@*W9;yZ*Y!1?r_p5sApTNA)*IRHl>Qtqrjj_>2GBPw=8ykM3 zrFi2%ANk!~@Mv$P2qo5mx(ii*49x)~=Er zm2u_3n#TLq(iO3W^*?Xuk(F%QETKQxEQB_hEP)XiYY!TaGSVX_pC&>l>6OUZ+-w#y zOAEc#f3xfb>Zaf~9Uy<*csM$vYCVVNWU&H0kHOxxE1-AbUy@1p z0v@(YsvhIa+=2Vzp8RH|^Y53XMUI!Gy&})XQggcw4}%)McDBXMSxEJo0~Cw1AqwiQ zb+o$uKdQcg%?8|4D?r{(6sR72TL~_GZHyB8Gs7D{g)U-gTz*um#vNcvFii@x*tkkc z(*z)3W%M&)#_)#SMK3;NH>I$O3e!m;ru<5z_9cv9u3m$N^n%xn`LCGMd&yk?Pv*Jo z%5wW9>$p^X0<$7Ih=Qh@B)QCz#A3GZXVb$MBgu+XYpxYu!N%Q}vao>RZ(vm84PeUP j8yn{uKKw5zd%yh6R`FYC()dWbj_(AWJF5)u*{i<*E~)%1 diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-38.pyc deleted file mode 100644 index ab1a4ff958f2b5e5926279032352fe237e057dd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2210 zcmcgu&2G~`5VrHvrco=7aP+NCN#g^T3N?s|zY`S#ammHn+LL6dy=!LIfeLXdkATE8 z^fh=04!LsT6}Z5R?S!O%w5rsNyq@*$%s2Dx?o8fpY_uI}JKw&CKU$9SlLw2fL4(Ki zm{-)rPV6SmfZw&mN!@|#vRo&*HmDVHgXH?4UdT<78-oVPEAi?VXV8Q?G~yOCk9ppG z<8;=3kyU5^#GN)Xfd)G6bVI5kAgBmJD>M3V4`C#Y1q@Ri=Lv-H(SnKrX>Rr9-u~W; zXRjkRv)F1hctVe%m>f%B#|&577hhK#ryax4LwKJ{1b?d%Qc%`(9=1Jd2sTIMWrw2> z!RQ<#Fue~N52YG~25j$q<#uT}SD}eeX4bEknXXrU2$e|T${7E%Q^HARhJ44PFw>G^ z@JFcgtm`pWe_yLB172#WQw3MiL7PB(V*E@*hhhYwMq;WUlzHqDgC%X}L_7i;W~e8U zw(tV|PH!yCoO+^h(by?Rq>1H4c5d#+9J+)lPDgn{E^%on6JYi)i0SjQ5=jOX!WRh}IDIcPUtkfz5 zM2&uxVKQM%xq{D2B%(2dnXqGDU^JE!DDGyNCrsb(R9cm_Vx`yj_$>7n5ZHjH(PNX8 zMn#@fru|Ogq!n0Pa9-B;wCS-z?;T|(f6;Q+TXf?7=C)0<&91k_VVTlWm4p`zmceA& zSjr!il8tX6%~+-D&2GV&*eP9e#h5Wv5WwA;g;4@R<=OmV8GooL@%NvLgbGtx7?vrG z=@_6q$eDVd2i2;|^QUK~+wFpLLs^rzqDY;FX!`WIja;!#99*SW(fu~TSf>yeh{ztL z@n9tR)>HUFu4F*!b_}Ud+Xip~7=W4ti986hBRkgWL2oB8l+m|mFo7UvwTy!U6jGIa zxLo0~qv_qHFCo#U4AGF@;aWlukGvC+xX=R$5*LIXh}{QTao80C!J!u`ji+5}lQ1$k*Uw^va2^zy-#3Hl*EFPvS+YWzYOPznSsa(|5OS1s;8m|NX+=?|a@?vuJ-k zT0EzpdQAiOCLZ^BC-d{pq~n`;H|yrTNiXkD`gYyR_VU4GK=VG|`^TFMp$|PifZ>O( z@7ej#&H4UYZya3xd8jl>!NW5t&s8{+7?w*7N=M&_&>Q=!Ka#1ES*3xAyp*WNoz>vv z@bvKb<(t(Vgt<@}kmZtB88BFAC^#VPyIos8szgST)R=33U0VE2KXsc1?P>pm|FOgU zPd@q8IZf{Fd0r4`Ts{dx`W$!2YUlC<&$r1D(#r&kt*WXh0Jmw#=9%2ON1cnZ6vceo zu0$z7EodVwQYdx!%BJTfqD1F&Nss_C1#ZcqB=-^xoTW*Yg-@GkYOkXWgk?41s4ZA4 z4=e;0Lbnk%(8x%wdX|VaGN(3Dt2Qy-+-;;*?Gi6>JFKmB&MY?Qu2UFUg*9mouf=GV z(FqO5KnIj)iTB4Ahlx#RG_nj3#Lx3w_ zsw&MTv^=#)6lqrRwM4ChqYdEBf?Z46#*Ldpp;8p3qc(ADSZ$@L!QNmt`*vLyqjR}w z{Mhh;!?c>uukWJ*%`_%y`+yomHSiXJVl% z1m(`!En2kK>ZqPr*it~oSuNQHUIYAII)1&DCcc|o_2p{2Wq@nUE!S%Jn%c(lpLH_s zVxM{knohDBQ6HnqU{lj>K6^MY8Z&&);xm~;tRO|uvVeFlG~Mk|s<OI%Yhjcc^gVbz3Tzs{>bfrZNjf?KD3i z9~3n+&+~_V=Lb@k_a=J|bu}oLk?FRlCY3Q(w diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_qt.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_qt.cpython-38.pyc deleted file mode 100644 index 01b88826f990c37372c32dda465bd7a1adc86138..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2120 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 O_;qWvc5l17eef4vYv7sy diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_scipy_signal.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_scipy_signal.cpython-38.pyc deleted file mode 100644 index 8118f3bc027a9cc6b4927ebf8289356db508ab73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2207 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 diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-38.pyc deleted file mode 100644 index d9dcdfe290c3c8f3f3423abf4a1d97f8ca0e69bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3621 zcmbss%W~s3%#S2?(#>{{J!;xZGUJWg>~v=Pm`-Vmjx|w8m6G!Cg`-5=L|t3*P)a85 zb$jX$^c(g!`We3V)P6!QEhsColgPVqN{?v(CO`lLK*HbL+^E2K{rex{x9640pBkAT zD}ek6-_(IAtn@2kHLMM)!&<*KtoQ3xjn@Y&!`1$34zIv}YyGtxUIn<(Zvea&Hh!)2 zo3buzVN*8WX})#0vc2)k=P1oo5{1S^lDtigH;FQ`3u&b3z!*fQDp2E{zhLLec5Tu) zKoso}KKV?^^C-=v62m0C97rLrGZ}|cZC5AH3wfQ(XfUO$#z`pC_tnYjC{U?9)6(Wg z4G;|9vgGEl$jG=IlD# zO-_F{g47TN+%n=Qyd@TJIX6et6loS@mubt$ksu5U=yaUP8|o;Pmti7uQZ6Y|<8O1I z^oVmw@;uB}$m=sX$_y(%{oErn&Myob;#7kFjWCg^5hs~3Qpr^m%BeaxLi9GHAWh57 z*kX=AHaHA^vE}p#7cSutV8Y>~OE{sJv~JbavStHVC=-|+z*1KSWG)3rpw!jwJo4(p zB0Sr@`s!wVj);5c?gs?87TvRnFnhvxArL^TfR@cJFTj-jPGKwB@d*Tq;{{N8SddTx#0p52Q1=|;#Q@JvnV8%^x zfbiq_<}4TF*wMN5G-gf?+5S_ReY#KC5q;XuK4l#bSrm2bB^-ur<`Rf@IQNsXurR@y zCJ}^l#viYj=DJND(M6W+^Cgr5c7Eb`%kJ8P%H{UZK3RT8%eKiLvW0^CB)1 z7uXgVGLz_@xH!LeXQU$pnSmLl5CQY@aylnyVX3_*;s`S9jzYPBOd{mhpgY69ir=$R_C`-v&DhJm22+xP`s)%NXuM z;Zmz*Xh7fGQ;0gSl_nwEq2-+7=2?s!>*i@(zVbGu!DCmuuUf_}p?HDZ#q}fP9%c6< zfO zGa64e;a6lTh*M~QhA(tCqSdKXYt`DnN_S}eIxL~v>yw5MVR9zKq*2IIx`9!3m?obV wq@B}g_oH<8rdIXT(32K4GjIy618vg$e%eX>psi1z!L(9)QGKRA_2zf~0a325X#fBK diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-38.pyc deleted file mode 100644 index d6a25884a2ceb68fce48fae749f74a203448ee13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4217 zcmeHKOK;mo5GE;#qU6|Zia06S0wsb55Cg>u5TFTyIB3u(3e+(A2v8LPL2*a&+SHQW zUB$K_^^#nB?xhF2J@rTQ(%(>^0FUjV$Y02%oh2!XbY!Q;6bK0p_c1fOGrRlk%vY~&W92>k#3x9IM)XkYWq-Y=r*)%efVNvB#$LT=rllH|>ck}V z$6C(<LA7=WBwl)GmX?{y43k)V$KYPc3UGdwXv{&4;SJ{UK^O_}21IOrsrr3JyX>96UjX3}?3aB_BiQ3~g#) zPk<1pWNu6B3z6E^c0111Q>1|f5&CmDw~6zJi@YM?AX{1Yc4cU#xM=YIc)84lGfr&O z|HCq$xwb#QT-z6AZO>Y#$y*9u_kAjJXsrP81wXDr}xjZH%7rz z+G_r%??NC;n<`_*xC0P8VoH!+FEpiSfGzk(1jz~*)?r~lLuk7N z!j4UxWt|z7n$@v;eq~vMb-HArf6@X#4#KfgL#I@!SN1}^6zZ?63 z+yS)tngEV*eHYJsH>CY;d?}`@NdHiNw?lZPG6Bd6N4~3?e?-xD!SJM*Vj;3Ng2p)cc1LL}G4# zedA_I-%aW&LyHqz-7EXtj}wak!P`A)i8!P(%|sG&H=-L-5dFc*cMyjnD3F-TU~%&r61+`y{o-zLT-v URjv`rE4FSMcCDqiYW8>k01jS5Vm*kxFb>u3M9%cD6;4-7NUs|K}0Cfz!m&7p;-CWb9+v9?ahogN_yUb zHYs@x9%EZ7UV#Se-4$F8iIF_=jK6Qb8QULscXyb#gD>B*}S|Y($h9mz9o%?CU+EyS4a!<7e zMB!UTs4a=cXi>}Dt)Y@;PJkDH0?dUd^-|PVZf(tz{R2VT!QA7{WC0`wDX~PUP46?e zMv%(C)qZ`|-W$Tqp)|CzScNY^cf4bK#G_vrw(Z?Nq;!Ol&-CdB2!*Eb6qQv?2^m~E kFbc4pyggbRy*_^TceZ{P{%|{e*2AAqd_-aTX*|9E8^le;<^TWy diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_typing.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_typing.cpython-38.pyc deleted file mode 100644 index bdf10557cc7cfc2106d3b58cb481881513ee1ae9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2376 zcmZ`)-ER{|5Wl@o`{FpCgr-E|TG0|CVppx&BGe)b7!*OQlsFVzRi}%0?ObBtU3b@k zxJe%f4}IaeuTCE-@o)6cSoN(>{0m4GojG5=pxxwVc4uaHXJ_U&ULPNKH5k`^`_umm zW`E=2^sr!Y6F%`f5UMpbN~qo?O#OG@r^vtH&vzk`VZrVMk>GX2V9MPyrtxdg| zr#5wfyEI4hz{jZDEU|k=V>X*QAZ+r`AX+Ay1KAA7rcp-qHLY}RaH%RJk3;Hh#__iB+A;U!ZW2bFa?zI%#mp#E9Iub`f4Hq~ zAcVKVWUvUftaRP=U{Kcfe80nFC|S?<7X|CKuX?!14A6)(+2@gmIyc>QGvRTdv?5PG+5edv1$hOtYZ_H{iPspZE&Mp0=g!6G`@n z)VGWSoiFT>EmK4ehfEQv*>ABB|!(!a@iL9`?o-(kGMqMb@N+^8hGax;#;C||1xi1`xOZ3i7D zD#57yDjPfqqY?G93@5wlQWvYz?}pnflOkg~0rz9>N9-xCJ_Wx-0fn@pG_l zVPKC2ViVDu2KiT*4CW*Tnr!KNfX|oYfb8qvYtf>qNn_jPH;A?mI2pLo+%uko=1aiL zzVVCkSbL&H`eSWRA6kc+w6`6;D$VBv&T>TaXhw~BZJ0aMhIwipl6_OUa%@=GgE`!T z_hz?3+N{CXDJs0+2zw297F7LWxm+%JCy>l)d?aoK-R>)*oK_r30A8JAMZF=HOXH9> zL?Wh5St$y+19OfgrmUaR#LvHzc>lZg>VxIG%e6bo!~$3OK=_aw=mg3_o^TVl&z{=n zH)<=Z52}rtvY~JE0$H;7G+uNbNqW7(p0!jCvxK*%B{U+lc-Y0%x&O~>1&qWT5KY&~ z9GN5^=mlazmQ8(@6bZisnlnJc5a27*9N&crW>`Xo0W5P6b3>Xbgho;eq*p;|pOHEs zy(M!X&mRD&M!*`}Z}44D#$G$@^f~k5zVyO2By6p}AzBa}=^<3SE4{F@DX(}N40P~p z2;UNC-9R!5-83`3TXH$pYl=%giL)sns+h%grM7ab_Hd1lqo#56zYNQp@CiIqgHVp3f;`oofeU8)7%n@o7)+1gGSm;Xcc60pKcGV1 zhsw~V`XLc@got!xZkQiIXy{VokWh18I|B~uCH6FXaPb{*JpKV-@#9H2>jP&L>9Qi_ z*Kc8PteMgnp9jVlk$i~c7zF$RER_r0kxTJ3l$&X7a}SL^LX{$u1DS1hNvTzi;MNXRY z)Fm~|Stk^daUXubBY|jE=55%-vALdlar*WYySZt<8 diff --git a/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-38.pyc deleted file mode 100644 index 2b875fd062fcbea72085bdff70076dbdc802d5ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 658 zcmZWnJ#X7E5T&Tkw06;tt&`BrL(HK|3K&5QrzkqqLklln1X{dUvL#X_=>Q2bX6@WH z8S^*#Gq`r@+^tJ{lsyC}fqS~s9r*6vaWNb|A$U%{|0v#3LVo(-@kuZ^Lo*WuL6$@W zf;K@*mo)Hxh<>;X(T_xYOO_GPyBNYv0+C2WdQ0woF8e}8N7rwr#%fiIyi#gw@(ZPN zTS2~9d_2!vC3X#re<2GQ1up$Golif!|BP-dl>k!)K65zUkI-gl<~4#Pn?M9NM9^<^ zjo%Fw;RM@7+GwtQIbM`>T!XYOtfd`=I>f&&o+)XpOBz-3#ykWr@@x-8dsY5ySfyHE z21*T9Nnq>R78*Kb*iP20<0bara(Qe(UxH>JFIiKsSa)SBCEt!un5iusW8Ido!7#p` zpRF{n -# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2015-2016 Ceridwen -# Copyright (c) 2015 Rene Zhang -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2019 Stanislav Levin -# Copyright (c) 2019 David Liu -# Copyright (c) 2019 Bryce Guinta -# Copyright (c) 2019 Frédéric Chapoton - -# 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, - 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 _container_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 _container_generic_transform(arg, context, klass, iterables, build_elts): - if isinstance(arg, klass): - return arg - elif isinstance(arg, iterables): - if all(isinstance(elt, nodes.Const) for elt in arg.elts): - elts = [elt.value for elt in arg.elts] - else: - # TODO: Does not handle deduplication for sets. - elts = [] - for element in arg.elts: - inferred = helpers.safe_infer(element, context=context) - if inferred: - evaluated_object = nodes.EvaluatedObject( - original=element, value=inferred - ) - elts.append(evaluated_object) - elif isinstance(arg, nodes.Dict): - # Dicts need to have consts as strings already. - 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_elements(elts=build_elts(elts)) - - -def _infer_builtin_container( - node, context, klass=None, iterables=None, build_elts=None -): - transform_func = partial( - _container_generic_transform, - context=context, - klass=klass, - iterables=iterables, - build_elts=build_elts, - ) - - return _container_generic_inference(node, context, klass, transform_func) - - -# pylint: disable=invalid-name -infer_tuple = partial( - _infer_builtin_container, - klass=nodes.Tuple, - iterables=( - nodes.List, - nodes.Set, - objects.FrozenSet, - objects.DictItems, - objects.DictKeys, - objects.DictValues, - ), - build_elts=tuple, -) - -infer_list = partial( - _infer_builtin_container, - klass=nodes.List, - iterables=( - nodes.Tuple, - nodes.Set, - objects.FrozenSet, - objects.DictItems, - objects.DictKeys, - objects.DictValues, - ), - build_elts=list, -) - -infer_set = partial( - _infer_builtin_container, - klass=nodes.Set, - iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys), - build_elts=set, -) - -infer_frozenset = partial( - _infer_builtin_container, - 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, context=context) - 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_property(node, context=None): - """Understand `property` class - - This only infers the output of `property` - call, not the arguments themselves. - """ - if len(node.args) < 1: - # Invalid property call. - raise UseInferenceDefault - - getter = node.args[0] - try: - inferred = next(getter.infer(context=context)) - except InferenceError: - raise UseInferenceDefault - - if not isinstance(inferred, (nodes.FunctionDef, nodes.Lambda)): - raise UseInferenceDefault - - return objects.Property( - function=inferred, - name=inferred.name, - doc=getattr(inferred, "doc", None), - lineno=node.lineno, - parent=node, - col_offset=node.col_offset, - ) - - -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(context=context) - 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, context=context) - 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, context=context) - 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, context=context) - 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, context=context)) - 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, context=context) - 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, context=context) - 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, StopIteration) 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, context=context) - 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_property, "property") -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/env/lib/python3.8/site-packages/astroid/brain/brain_collections.py b/env/lib/python3.8/site-packages/astroid/brain/brain_collections.py deleted file mode 100644 index 669c6ca4..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_collections.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- 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 -# Copyright (c) 2019 Hugo van Kemenade - -# 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 - - -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) - 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] - 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/env/lib/python3.8/site-packages/astroid/brain/brain_crypt.py b/env/lib/python3.8/site-packages/astroid/brain/brain_crypt.py deleted file mode 100644 index 491ee23c..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_crypt.py +++ /dev/null @@ -1,26 +0,0 @@ -# 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 - -PY37 = sys.version_info >= (3, 7) - -if PY37: - # Since Python 3.7 Hashing Methods are added - # dynamically to globals() - - def _re_transform(): - return astroid.parse( - """ - from collections import namedtuple - _Method = namedtuple('_Method', 'name ident salt_chars total_size') - - METHOD_SHA512 = _Method('SHA512', '6', 16, 106) - METHOD_SHA256 = _Method('SHA256', '5', 16, 63) - METHOD_BLOWFISH = _Method('BLOWFISH', 2, 'b', 22) - METHOD_MD5 = _Method('MD5', '1', 8, 34) - METHOD_CRYPT = _Method('CRYPT', None, 2, 13) - """ - ) - - astroid.register_module_extender(astroid.MANAGER, "crypt", _re_transform) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_curses.py b/env/lib/python3.8/site-packages/astroid/brain/brain_curses.py deleted file mode 100644 index 68e88b90..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_curses.py +++ /dev/null @@ -1,179 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_dataclasses.py b/env/lib/python3.8/site-packages/astroid/brain/brain_dataclasses.py deleted file mode 100644 index 7a25e0c6..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_dataclasses.py +++ /dev/null @@ -1,50 +0,0 @@ -# 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 hook for the dataclasses library -""" - -import astroid -from astroid import MANAGER - - -DATACLASSES_DECORATORS = frozenset(("dataclasses.dataclass", "dataclass")) - - -def is_decorated_with_dataclass(node, decorator_names=DATACLASSES_DECORATORS): - """Return True if a decorated node has a `dataclass` decorator applied.""" - if not node.decorators: - return False - for decorator_attribute in node.decorators.nodes: - if isinstance(decorator_attribute, astroid.Call): # decorator with arguments - decorator_attribute = decorator_attribute.func - if decorator_attribute.as_string() in decorator_names: - return True - return False - - -def dataclass_transform(node): - """Rewrite a dataclass to be easily understood by pylint""" - - for assign_node in node.body: - if not isinstance(assign_node, (astroid.AnnAssign, astroid.Assign)): - continue - - targets = ( - assign_node.targets - if hasattr(assign_node, "targets") - else [assign_node.target] - ) - for target in targets: - rhs_node = astroid.Unknown( - lineno=assign_node.lineno, - col_offset=assign_node.col_offset, - parent=assign_node, - ) - node.instance_attrs[target.name] = [rhs_node] - node.locals[target.name] = [rhs_node] - - -MANAGER.register_transform( - astroid.ClassDef, dataclass_transform, is_decorated_with_dataclass -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_dateutil.py b/env/lib/python3.8/site-packages/astroid/brain/brain_dateutil.py deleted file mode 100644 index 9fdb9fde..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_dateutil.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2015-2016, 2018 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/env/lib/python3.8/site-packages/astroid/brain/brain_fstrings.py b/env/lib/python3.8/site-packages/astroid/brain/brain_fstrings.py deleted file mode 100644 index 298d58af..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_fstrings.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2017-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 -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/env/lib/python3.8/site-packages/astroid/brain/brain_functools.py b/env/lib/python3.8/site-packages/astroid/brain/brain_functools.py deleted file mode 100644 index d6c60691..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_functools.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright (c) 2016, 2018-2020 Claudiu Popa -# Copyright (c) 2018 hippo91 -# 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, context=context) - 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.posonlyargs 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/env/lib/python3.8/site-packages/astroid/brain/brain_gi.py b/env/lib/python3.8/site-packages/astroid/brain/brain_gi.py deleted file mode 100644 index e49f3a22..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_gi.py +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014 Google, Inc. -# Copyright (c) 2014 Cole Robinson -# Copyright (c) 2015-2016, 2018 Claudiu Popa -# Copyright (c) 2015-2016 Ceridwen -# Copyright (c) 2015 David Shea -# Copyright (c) 2016 Jakub Wilk -# Copyright (c) 2016 Giuseppe Scrivano -# Copyright (c) 2018 Christoph Reiter -# Copyright (c) 2019 Philipp Hörist - -# 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*$" - -_special_methods = frozenset( - { - "__lt__", - "__le__", - "__eq__", - "__ne__", - "__ge__", - "__gt__", - "__iter__", - "__getitem__", - "__setitem__", - "__delitem__", - "__len__", - "__bool__", - "__nonzero__", - "__next__", - "__str__", - "__len__", - "__contains__", - "__enter__", - "__exit__", - "__repr__", - "__getattr__", - "__setattr__", - "__delattr__", - "__del__", - "__hash__", - } -) - - -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("__") and name not in _special_methods: - 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/env/lib/python3.8/site-packages/astroid/brain/brain_hashlib.py b/env/lib/python3.8/site-packages/astroid/brain/brain_hashlib.py deleted file mode 100644 index eb34e159..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_hashlib.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2016, 2018 Claudiu Popa -# Copyright (c) 2018 David Poirier -# Copyright (c) 2018 wgehalo -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_http.py b/env/lib/python3.8/site-packages/astroid/brain/brain_http.py deleted file mode 100644 index b16464e8..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_http.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright (c) 2018-2019 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(): - code = textwrap.dedent( - """ - from collections import namedtuple - _HTTPStatus = namedtuple('_HTTPStatus', 'value phrase description') - - class HTTPStatus: - - @property - def phrase(self): - return "" - @property - def value(self): - return 0 - @property - def description(self): - return "" - - # informational - CONTINUE = _HTTPStatus(100, 'Continue', 'Request received, please continue') - SWITCHING_PROTOCOLS = _HTTPStatus(101, 'Switching Protocols', - 'Switching to new protocol; obey Upgrade header') - PROCESSING = _HTTPStatus(102, 'Processing', '') - OK = _HTTPStatus(200, 'OK', 'Request fulfilled, document follows') - CREATED = _HTTPStatus(201, 'Created', 'Document created, URL follows') - ACCEPTED = _HTTPStatus(202, 'Accepted', - 'Request accepted, processing continues off-line') - NON_AUTHORITATIVE_INFORMATION = _HTTPStatus(203, - 'Non-Authoritative Information', 'Request fulfilled from cache') - NO_CONTENT = _HTTPStatus(204, 'No Content', 'Request fulfilled, nothing follows') - RESET_CONTENT =_HTTPStatus(205, 'Reset Content', 'Clear input form for further input') - PARTIAL_CONTENT = _HTTPStatus(206, 'Partial Content', 'Partial content follows') - MULTI_STATUS = _HTTPStatus(207, 'Multi-Status', '') - ALREADY_REPORTED = _HTTPStatus(208, 'Already Reported', '') - IM_USED = _HTTPStatus(226, 'IM Used', '') - MULTIPLE_CHOICES = _HTTPStatus(300, 'Multiple Choices', - 'Object has several resources -- see URI list') - MOVED_PERMANENTLY = _HTTPStatus(301, 'Moved Permanently', - 'Object moved permanently -- see URI list') - FOUND = _HTTPStatus(302, 'Found', 'Object moved temporarily -- see URI list') - SEE_OTHER = _HTTPStatus(303, 'See Other', 'Object moved -- see Method and URL list') - NOT_MODIFIED = _HTTPStatus(304, 'Not Modified', - 'Document has not changed since given time') - USE_PROXY = _HTTPStatus(305, 'Use Proxy', - 'You must use proxy specified in Location to access this resource') - TEMPORARY_REDIRECT = _HTTPStatus(307, 'Temporary Redirect', - 'Object moved temporarily -- see URI list') - PERMANENT_REDIRECT = _HTTPStatus(308, 'Permanent Redirect', - 'Object moved permanently -- see URI list') - BAD_REQUEST = _HTTPStatus(400, 'Bad Request', - 'Bad request syntax or unsupported method') - UNAUTHORIZED = _HTTPStatus(401, 'Unauthorized', - 'No permission -- see authorization schemes') - PAYMENT_REQUIRED = _HTTPStatus(402, 'Payment Required', - 'No payment -- see charging schemes') - FORBIDDEN = _HTTPStatus(403, 'Forbidden', - 'Request forbidden -- authorization will not help') - NOT_FOUND = _HTTPStatus(404, 'Not Found', - 'Nothing matches the given URI') - METHOD_NOT_ALLOWED = _HTTPStatus(405, 'Method Not Allowed', - 'Specified method is invalid for this resource') - NOT_ACCEPTABLE = _HTTPStatus(406, 'Not Acceptable', - 'URI not available in preferred format') - PROXY_AUTHENTICATION_REQUIRED = _HTTPStatus(407, - 'Proxy Authentication Required', - 'You must authenticate with this proxy before proceeding') - REQUEST_TIMEOUT = _HTTPStatus(408, 'Request Timeout', - 'Request timed out; try again later') - CONFLICT = _HTTPStatus(409, 'Conflict', 'Request conflict') - GONE = _HTTPStatus(410, 'Gone', - 'URI no longer exists and has been permanently removed') - LENGTH_REQUIRED = _HTTPStatus(411, 'Length Required', - 'Client must specify Content-Length') - PRECONDITION_FAILED = _HTTPStatus(412, 'Precondition Failed', - 'Precondition in headers is false') - REQUEST_ENTITY_TOO_LARGE = _HTTPStatus(413, 'Request Entity Too Large', - 'Entity is too large') - REQUEST_URI_TOO_LONG = _HTTPStatus(414, 'Request-URI Too Long', - 'URI is too long') - UNSUPPORTED_MEDIA_TYPE = _HTTPStatus(415, 'Unsupported Media Type', - 'Entity body in unsupported format') - REQUESTED_RANGE_NOT_SATISFIABLE = _HTTPStatus(416, - 'Requested Range Not Satisfiable', - 'Cannot satisfy request range') - EXPECTATION_FAILED = _HTTPStatus(417, 'Expectation Failed', - 'Expect condition could not be satisfied') - MISDIRECTED_REQUEST = _HTTPStatus(421, 'Misdirected Request', - 'Server is not able to produce a response') - UNPROCESSABLE_ENTITY = _HTTPStatus(422, 'Unprocessable Entity') - LOCKED = _HTTPStatus(423, 'Locked') - FAILED_DEPENDENCY = _HTTPStatus(424, 'Failed Dependency') - UPGRADE_REQUIRED = _HTTPStatus(426, 'Upgrade Required') - PRECONDITION_REQUIRED = _HTTPStatus(428, 'Precondition Required', - 'The origin server requires the request to be conditional') - TOO_MANY_REQUESTS = _HTTPStatus(429, 'Too Many Requests', - 'The user has sent too many requests in ' - 'a given amount of time ("rate limiting")') - REQUEST_HEADER_FIELDS_TOO_LARGE = _HTTPStatus(431, - 'Request Header Fields Too Large', - 'The server is unwilling to process the request because its header ' - 'fields are too large') - UNAVAILABLE_FOR_LEGAL_REASONS = _HTTPStatus(451, - 'Unavailable For Legal Reasons', - 'The server is denying access to the ' - 'resource as a consequence of a legal demand') - INTERNAL_SERVER_ERROR = _HTTPStatus(500, 'Internal Server Error', - 'Server got itself in trouble') - NOT_IMPLEMENTED = _HTTPStatus(501, 'Not Implemented', - 'Server does not support this operation') - BAD_GATEWAY = _HTTPStatus(502, 'Bad Gateway', - 'Invalid responses from another server/proxy') - SERVICE_UNAVAILABLE = _HTTPStatus(503, 'Service Unavailable', - 'The server cannot process the request due to a high load') - GATEWAY_TIMEOUT = _HTTPStatus(504, 'Gateway Timeout', - 'The gateway server did not receive a timely response') - HTTP_VERSION_NOT_SUPPORTED = _HTTPStatus(505, 'HTTP Version Not Supported', - 'Cannot fulfill request') - VARIANT_ALSO_NEGOTIATES = _HTTPStatus(506, 'Variant Also Negotiates') - INSUFFICIENT_STORAGE = _HTTPStatus(507, 'Insufficient Storage') - LOOP_DETECTED = _HTTPStatus(508, 'Loop Detected') - NOT_EXTENDED = _HTTPStatus(510, 'Not Extended') - NETWORK_AUTHENTICATION_REQUIRED = _HTTPStatus(511, - 'Network Authentication Required', - 'The client needs to authenticate to gain network access') - """ - ) - return AstroidBuilder(astroid.MANAGER).string_build(code) - - -def _http_client_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", _http_transform) -astroid.register_module_extender(astroid.MANAGER, "http.client", _http_client_transform) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_io.py b/env/lib/python3.8/site-packages/astroid/brain/brain_io.py deleted file mode 100644 index c7453112..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_io.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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 - -"""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/env/lib/python3.8/site-packages/astroid/brain/brain_mechanize.py b/env/lib/python3.8/site-packages/astroid/brain/brain_mechanize.py deleted file mode 100644 index ef62c53b..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_mechanize.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014 Google, Inc. -# Copyright (c) 2015-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 - -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/env/lib/python3.8/site-packages/astroid/brain/brain_multiprocessing.py b/env/lib/python3.8/site-packages/astroid/brain/brain_multiprocessing.py deleted file mode 100644 index 3629b032..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_multiprocessing.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2016, 2018 Claudiu Popa -# Copyright (c) 2019 Hugo van Kemenade - -# 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 - - -def _multiprocessing_transform(): - module = astroid.parse( - """ - from multiprocessing.managers import SyncManager - def Manager(): - return SyncManager() - """ - ) - # 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/env/lib/python3.8/site-packages/astroid/brain/brain_namedtuple_enum.py b/env/lib/python3.8/site-packages/astroid/brain/brain_namedtuple_enum.py deleted file mode 100644 index 13fcf793..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_namedtuple_enum.py +++ /dev/null @@ -1,455 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2013-2014 Google, Inc. -# Copyright (c) 2014-2020 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 -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2019 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 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() - - attributes = [attr for attr in attributes if " " not in attr] - - # 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, context=context) - 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] - else: - continue - - 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] - - for assign in class_node.body: - if not isinstance(assign, nodes.Assign): - continue - - for target in assign.targets: - attr = target.name - generated_class_node.locals[attr] = class_node.locals[attr] - - 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/env/lib/python3.8/site-packages/astroid/brain/brain_nose.py b/env/lib/python3.8/site-packages/astroid/brain/brain_nose.py deleted file mode 100644 index d0280a3f..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_nose.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2015-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 - - -"""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/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py deleted file mode 100644 index 62dfe991..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2019 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.core.fromnumeric module.""" - -import astroid - - -def numpy_core_fromnumeric_transform(): - return astroid.parse( - """ - def sum(a, axis=None, dtype=None, out=None, keepdims=None, initial=None): - return numpy.ndarray([0, 0]) - """ - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.core.fromnumeric", numpy_core_fromnumeric_transform -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_function_base.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_function_base.py deleted file mode 100644 index 58aa0a98..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_function_base.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2019 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.core.function_base module.""" - -import functools -import astroid -from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member - - -METHODS_TO_BE_INFERRED = { - "linspace": """def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0): - return numpy.ndarray([0, 0])""", - "logspace": """def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0): - return numpy.ndarray([0, 0])""", - "geomspace": """def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): - return numpy.ndarray([0, 0])""", -} - -for func_name, func_src in METHODS_TO_BE_INFERRED.items(): - inference_function = functools.partial(infer_numpy_member, func_src) - astroid.MANAGER.register_transform( - astroid.Attribute, - astroid.inference_tip(inference_function), - functools.partial(looks_like_numpy_member, func_name), - ) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_multiarray.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_multiarray.py deleted file mode 100644 index b2e32bc8..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_multiarray.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2019-2020 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.core.multiarray module.""" - -import functools -import astroid -from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member - - -def numpy_core_multiarray_transform(): - return astroid.parse( - """ - # different functions defined in multiarray.py - def inner(a, b): - return numpy.ndarray([0, 0]) - - def vdot(a, b): - return numpy.ndarray([0, 0]) - """ - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.core.multiarray", numpy_core_multiarray_transform -) - - -METHODS_TO_BE_INFERRED = { - "array": """def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0): - return numpy.ndarray([0, 0])""", - "dot": """def dot(a, b, out=None): - return numpy.ndarray([0, 0])""", - "empty_like": """def empty_like(a, dtype=None, order='K', subok=True): - return numpy.ndarray((0, 0))""", - "concatenate": """def concatenate(arrays, axis=None, out=None): - return numpy.ndarray((0, 0))""", - "where": """def where(condition, x=None, y=None): - return numpy.ndarray([0, 0])""", - "empty": """def empty(shape, dtype=float, order='C'): - return numpy.ndarray([0, 0])""", - "bincount": """def bincount(x, weights=None, minlength=0): - return numpy.ndarray([0, 0])""", - "busday_count": """def busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None): - return numpy.ndarray([0, 0])""", - "busday_offset": """def busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None): - return numpy.ndarray([0, 0])""", - "can_cast": """def can_cast(from_, to, casting='safe'): - return True""", - "copyto": """def copyto(dst, src, casting='same_kind', where=True): - return None""", - "datetime_as_string": """def datetime_as_string(arr, unit=None, timezone='naive', casting='same_kind'): - return numpy.ndarray([0, 0])""", - "is_busday": """def is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None): - return numpy.ndarray([0, 0])""", - "lexsort": """def lexsort(keys, axis=-1): - return numpy.ndarray([0, 0])""", - "may_share_memory": """def may_share_memory(a, b, max_work=None): - return True""", - # Not yet available because dtype is not yet present in those brains - # "min_scalar_type": """def min_scalar_type(a): - # return numpy.dtype('int16')""", - "packbits": """def packbits(a, axis=None, bitorder='big'): - return numpy.ndarray([0, 0])""", - # Not yet available because dtype is not yet present in those brains - # "result_type": """def result_type(*arrays_and_dtypes): - # return numpy.dtype('int16')""", - "shares_memory": """def shares_memory(a, b, max_work=None): - return True""", - "unpackbits": """def unpackbits(a, axis=None, count=None, bitorder='big'): - return numpy.ndarray([0, 0])""", - "unravel_index": """def unravel_index(indices, shape, order='C'): - return (numpy.ndarray([0, 0]),)""", - "zeros": """def zeros(shape, dtype=float, order='C'): - return numpy.ndarray([0, 0])""", -} - -for method_name, function_src in METHODS_TO_BE_INFERRED.items(): - inference_function = functools.partial(infer_numpy_member, function_src) - astroid.MANAGER.register_transform( - astroid.Attribute, - astroid.inference_tip(inference_function), - functools.partial(looks_like_numpy_member, method_name), - ) - astroid.MANAGER.register_transform( - astroid.Name, - astroid.inference_tip(inference_function), - functools.partial(looks_like_numpy_member, method_name), - ) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numeric.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numeric.py deleted file mode 100644 index 2a6f37e3..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numeric.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2019 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.core.numeric module.""" - -import functools -import astroid -from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member - - -def numpy_core_numeric_transform(): - return astroid.parse( - """ - # different functions defined in numeric.py - import numpy - def zeros_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) - def ones_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) - def full_like(a, fill_value, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) - """ - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.core.numeric", numpy_core_numeric_transform -) - - -METHODS_TO_BE_INFERRED = { - "ones": """def ones(shape, dtype=None, order='C'): - return numpy.ndarray([0, 0])""" -} - - -for method_name, function_src in METHODS_TO_BE_INFERRED.items(): - inference_function = functools.partial(infer_numpy_member, function_src) - astroid.MANAGER.register_transform( - astroid.Attribute, - astroid.inference_tip(inference_function), - functools.partial(looks_like_numpy_member, method_name), - ) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numerictypes.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numerictypes.py deleted file mode 100644 index 6ac4a146..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_numerictypes.py +++ /dev/null @@ -1,254 +0,0 @@ -# Copyright (c) 2019-2020 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 - -# TODO(hippo91) : correct the methods signature. - -"""Astroid hooks for numpy.core.numerictypes module.""" - -import astroid - - -def numpy_core_numerictypes_transform(): - # TODO: Uniformize the generic API with the ndarray one. - # According to numpy doc the generic object should expose - # the same API than ndarray. This has been done here partially - # through the astype method. - 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, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0]) - 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 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): - def __init__(self, nb, unit=None): 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): - def __init__(self, nb, unit=None): 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 - """ - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_umath.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_umath.py deleted file mode 100644 index 897961ea..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_core_umath.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright (c) 2019 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.core.umath module.""" - -import astroid - - -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( - """ - class FakeUfunc: - def __init__(self): - self.__doc__ = str() - self.__name__ = str() - self.nin = 0 - self.nout = 0 - self.nargs = 0 - self.ntypes = 0 - self.types = None - self.identity = None - self.signature = None - - @classmethod - def reduce(cls, a, axis=None, dtype=None, out=None): - return numpy.ndarray([0, 0]) - - @classmethod - def accumulate(cls, array, axis=None, dtype=None, out=None): - return numpy.ndarray([0, 0]) - - @classmethod - def reduceat(cls, a, indices, axis=None, dtype=None, out=None): - return numpy.ndarray([0, 0]) - - @classmethod - def outer(cls, A, B, **kwargs): - return numpy.ndarray([0, 0]) - - @classmethod - def at(cls, a, indices, b=None): - return numpy.ndarray([0, 0]) - - class FakeUfuncOneArg(FakeUfunc): - def __call__(self, x, {opt_args:s}): - return numpy.ndarray([0, 0]) - - class FakeUfuncOneArgBis(FakeUfunc): - def __call__(self, x, {opt_args:s}): - return numpy.ndarray([0, 0]), numpy.ndarray([0, 0]) - - class FakeUfuncTwoArgs(FakeUfunc): - def __call__(self, x1, x2, {opt_args:s}): - return numpy.ndarray([0, 0]) - - # Constants - e = 2.718281828459045 - euler_gamma = 0.5772156649015329 - - # One arg functions with optional kwargs - arccos = FakeUfuncOneArg() - arccosh = FakeUfuncOneArg() - arcsin = FakeUfuncOneArg() - arcsinh = FakeUfuncOneArg() - arctan = FakeUfuncOneArg() - arctanh = FakeUfuncOneArg() - cbrt = FakeUfuncOneArg() - conj = FakeUfuncOneArg() - conjugate = FakeUfuncOneArg() - cosh = FakeUfuncOneArg() - deg2rad = FakeUfuncOneArg() - exp2 = FakeUfuncOneArg() - expm1 = FakeUfuncOneArg() - fabs = FakeUfuncOneArg() - frexp = FakeUfuncOneArgBis() - isfinite = FakeUfuncOneArg() - isinf = FakeUfuncOneArg() - log = FakeUfuncOneArg() - log1p = FakeUfuncOneArg() - log2 = FakeUfuncOneArg() - logical_not = FakeUfuncOneArg() - modf = FakeUfuncOneArgBis() - negative = FakeUfuncOneArg() - positive = FakeUfuncOneArg() - rad2deg = FakeUfuncOneArg() - reciprocal = FakeUfuncOneArg() - rint = FakeUfuncOneArg() - sign = FakeUfuncOneArg() - signbit = FakeUfuncOneArg() - sinh = FakeUfuncOneArg() - spacing = FakeUfuncOneArg() - square = FakeUfuncOneArg() - tan = FakeUfuncOneArg() - tanh = FakeUfuncOneArg() - trunc = FakeUfuncOneArg() - - # Two args functions with optional kwargs - bitwise_and = FakeUfuncTwoArgs() - bitwise_or = FakeUfuncTwoArgs() - bitwise_xor = FakeUfuncTwoArgs() - copysign = FakeUfuncTwoArgs() - divide = FakeUfuncTwoArgs() - divmod = FakeUfuncTwoArgs() - equal = FakeUfuncTwoArgs() - float_power = FakeUfuncTwoArgs() - floor_divide = FakeUfuncTwoArgs() - fmax = FakeUfuncTwoArgs() - fmin = FakeUfuncTwoArgs() - fmod = FakeUfuncTwoArgs() - greater = FakeUfuncTwoArgs() - gcd = FakeUfuncTwoArgs() - hypot = FakeUfuncTwoArgs() - heaviside = FakeUfuncTwoArgs() - lcm = FakeUfuncTwoArgs() - ldexp = FakeUfuncTwoArgs() - left_shift = FakeUfuncTwoArgs() - less = FakeUfuncTwoArgs() - logaddexp = FakeUfuncTwoArgs() - logaddexp2 = FakeUfuncTwoArgs() - logical_and = FakeUfuncTwoArgs() - logical_or = FakeUfuncTwoArgs() - logical_xor = FakeUfuncTwoArgs() - maximum = FakeUfuncTwoArgs() - minimum = FakeUfuncTwoArgs() - nextafter = FakeUfuncTwoArgs() - not_equal = FakeUfuncTwoArgs() - power = FakeUfuncTwoArgs() - remainder = FakeUfuncTwoArgs() - right_shift = FakeUfuncTwoArgs() - subtract = FakeUfuncTwoArgs() - true_divide = FakeUfuncTwoArgs() - """.format( - opt_args=ufunc_optional_keyword_arguments - ) - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_ndarray.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_ndarray.py deleted file mode 100644 index d40a7dd0..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_ndarray.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (c) 2015-2016, 2018-2019 Claudiu Popa -# Copyright (c) 2016 Ceridwen -# Copyright (c) 2017-2020 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 ndarray class.""" - -import functools -import astroid - - -def infer_numpy_ndarray(node, context=None): - ndarray = """ - 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 = np.ndarray([0, 0]) - self.itemsize = None - self.nbytes = None - self.ndim = None - self.real = np.ndarray([0, 0]) - self.shape = numpy.ndarray([0, 0]) - self.size = None - self.strides = None - - def __abs__(self): return numpy.ndarray([0, 0]) - def __add__(self, value): return numpy.ndarray([0, 0]) - def __and__(self, value): return numpy.ndarray([0, 0]) - def __array__(self, dtype=None): return numpy.ndarray([0, 0]) - def __array_wrap__(self, obj): return numpy.ndarray([0, 0]) - def __contains__(self, key): return True - def __copy__(self): return numpy.ndarray([0, 0]) - def __deepcopy__(self, memo): return numpy.ndarray([0, 0]) - def __divmod__(self, value): return (numpy.ndarray([0, 0]), numpy.ndarray([0, 0])) - def __eq__(self, value): return numpy.ndarray([0, 0]) - def __float__(self): return 0. - def __floordiv__(self): return numpy.ndarray([0, 0]) - def __ge__(self, value): return numpy.ndarray([0, 0]) - def __getitem__(self, key): return uninferable - def __gt__(self, value): return numpy.ndarray([0, 0]) - def __iadd__(self, value): return numpy.ndarray([0, 0]) - def __iand__(self, value): return numpy.ndarray([0, 0]) - def __ifloordiv__(self, value): return numpy.ndarray([0, 0]) - def __ilshift__(self, value): return numpy.ndarray([0, 0]) - def __imod__(self, value): return numpy.ndarray([0, 0]) - def __imul__(self, value): return numpy.ndarray([0, 0]) - def __int__(self): return 0 - def __invert__(self): return numpy.ndarray([0, 0]) - def __ior__(self, value): return numpy.ndarray([0, 0]) - def __ipow__(self, value): return numpy.ndarray([0, 0]) - def __irshift__(self, value): return numpy.ndarray([0, 0]) - def __isub__(self, value): return numpy.ndarray([0, 0]) - def __itruediv__(self, value): return numpy.ndarray([0, 0]) - def __ixor__(self, value): return numpy.ndarray([0, 0]) - def __le__(self, value): return numpy.ndarray([0, 0]) - def __len__(self): return 1 - def __lshift__(self, value): return numpy.ndarray([0, 0]) - def __lt__(self, value): return numpy.ndarray([0, 0]) - def __matmul__(self, value): return numpy.ndarray([0, 0]) - def __mod__(self, value): return numpy.ndarray([0, 0]) - def __mul__(self, value): return numpy.ndarray([0, 0]) - def __ne__(self, value): return numpy.ndarray([0, 0]) - def __neg__(self): return numpy.ndarray([0, 0]) - def __or__(self): return numpy.ndarray([0, 0]) - def __pos__(self): return numpy.ndarray([0, 0]) - def __pow__(self): return numpy.ndarray([0, 0]) - def __repr__(self): return str() - def __rshift__(self): return numpy.ndarray([0, 0]) - def __setitem__(self, key, value): return uninferable - def __str__(self): return str() - def __sub__(self, value): return numpy.ndarray([0, 0]) - def __truediv__(self, value): return numpy.ndarray([0, 0]) - def __xor__(self, value): return numpy.ndarray([0, 0]) - def all(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def any(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def argmax(self, axis=None, out=None): return np.ndarray([0, 0]) - def argmin(self, axis=None, out=None): return np.ndarray([0, 0]) - def argpartition(self, kth, axis=-1, kind='introselect', order=None): return np.ndarray([0, 0]) - def argsort(self, axis=-1, kind='quicksort', order=None): return np.ndarray([0, 0]) - def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0]) - def byteswap(self, inplace=False): return np.ndarray([0, 0]) - def choose(self, choices, out=None, mode='raise'): return np.ndarray([0, 0]) - def clip(self, min=None, max=None, out=None): return np.ndarray([0, 0]) - def compress(self, condition, axis=None, out=None): return np.ndarray([0, 0]) - def conj(self): return np.ndarray([0, 0]) - def conjugate(self): return np.ndarray([0, 0]) - def copy(self, order='C'): return np.ndarray([0, 0]) - def cumprod(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0]) - def cumsum(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0]) - def diagonal(self, offset=0, axis1=0, axis2=1): return np.ndarray([0, 0]) - def dot(self, b, out=None): return np.ndarray([0, 0]) - def dump(self, file): return None - def dumps(self): return str() - def fill(self, value): return None - def flatten(self, order='C'): return np.ndarray([0, 0]) - def getfield(self, dtype, offset=0): return np.ndarray([0, 0]) - def item(self, *args): return uninferable - def itemset(self, *args): return None - def max(self, axis=None, out=None): return np.ndarray([0, 0]) - def mean(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def min(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def newbyteorder(self, new_order='S'): return np.ndarray([0, 0]) - def nonzero(self): return (1,) - def partition(self, kth, axis=-1, kind='introselect', order=None): return None - def prod(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def ptp(self, axis=None, out=None): return np.ndarray([0, 0]) - def put(self, indices, values, mode='raise'): return None - def ravel(self, order='C'): return np.ndarray([0, 0]) - def repeat(self, repeats, axis=None): return np.ndarray([0, 0]) - def reshape(self, shape, order='C'): return np.ndarray([0, 0]) - def resize(self, new_shape, refcheck=True): return None - def round(self, decimals=0, out=None): return np.ndarray([0, 0]) - def searchsorted(self, v, side='left', sorter=None): return np.ndarray([0, 0]) - def setfield(self, val, dtype, offset=0): return None - def setflags(self, write=None, align=None, uic=None): return None - def sort(self, axis=-1, kind='quicksort', order=None): return None - def squeeze(self, axis=None): return np.ndarray([0, 0]) - def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0]) - def sum(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) - def swapaxes(self, axis1, axis2): return np.ndarray([0, 0]) - def take(self, indices, axis=None, out=None, mode='raise'): return np.ndarray([0, 0]) - def tobytes(self, order='C'): return b'' - def tofile(self, fid, sep="", format="%s"): return None - def tolist(self, ): return [] - def tostring(self, order='C'): return b'' - def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return np.ndarray([0, 0]) - def transpose(self, *axes): return np.ndarray([0, 0]) - def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0]) - def view(self, dtype=None, type=None): return np.ndarray([0, 0]) - """ - node = astroid.extract_node(ndarray) - return node.infer(context=context) - - -def _looks_like_numpy_ndarray(node): - return isinstance(node, astroid.Attribute) and node.attrname == "ndarray" - - -astroid.MANAGER.register_transform( - astroid.Attribute, - astroid.inference_tip(infer_numpy_ndarray), - _looks_like_numpy_ndarray, -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_random_mtrand.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_random_mtrand.py deleted file mode 100644 index cffdceef..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_random_mtrand.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2019 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 - -# TODO(hippo91) : correct the functions return types -"""Astroid hooks for numpy.random.mtrand module.""" - -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'): - import numpy - return numpy.ndarray((1,1)) - 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 - """ - ) - - -astroid.register_module_extender( - astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_utils.py b/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_utils.py deleted file mode 100644 index b29d2719..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_numpy_utils.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2019-2020 hippo91 -# Copyright (c) 2019 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 - - -"""Different utilities for the numpy brains""" - - -import astroid - - -def infer_numpy_member(src, node, context=None): - node = astroid.extract_node(src) - return node.infer(context=context) - - -def _is_a_numpy_module(node: astroid.node_classes.Name) -> bool: - """ - Returns True if the node is a representation of a numpy module. - - For example in : - import numpy as np - x = np.linspace(1, 2) - The node is a representation of the numpy module. - - :param node: node to test - :return: True if the node is a representation of the numpy module. - """ - module_nickname = node.name - potential_import_target = [ - x for x in node.lookup(module_nickname)[1] if isinstance(x, astroid.Import) - ] - for target in potential_import_target: - if ("numpy", module_nickname) in target.names: - return True - return False - - -def looks_like_numpy_member( - member_name: str, node: astroid.node_classes.NodeNG -) -> bool: - """ - Returns True if the node is a member of numpy whose - name is member_name. - - :param member_name: name of the member - :param node: node to test - :return: True if the node is a member of numpy - """ - if ( - isinstance(node, astroid.Attribute) - and node.attrname == member_name - and isinstance(node.expr, astroid.Name) - and _is_a_numpy_module(node.expr) - ): - return True - if ( - isinstance(node, astroid.Name) - and node.name == member_name - and node.root().name.startswith("numpy") - ): - return True - return False diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_pkg_resources.py b/env/lib/python3.8/site-packages/astroid/brain/brain_pkg_resources.py deleted file mode 100644 index 25e76495..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_pkg_resources.py +++ /dev/null @@ -1,75 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_pytest.py b/env/lib/python3.8/site-packages/astroid/brain/brain_pytest.py deleted file mode 100644 index 56202ab8..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_pytest.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (c) 2014-2016, 2018 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/env/lib/python3.8/site-packages/astroid/brain/brain_qt.py b/env/lib/python3.8/site-packages/astroid/brain/brain_qt.py deleted file mode 100644 index b703b373..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_qt.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2015-2016, 2018 Claudiu Popa -# Copyright (c) 2016 Ceridwen -# Copyright (c) 2017 Roy Wright -# Copyright (c) 2018 Ashley Whetter -# Copyright (c) 2019 Antoine Boellinger - -# 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() in ("PySide.QtCore.Signal", "PySide2.QtCore.Signal"), -) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_random.py b/env/lib/python3.8/site-packages/astroid/brain/brain_random.py deleted file mode 100644 index 5ec858a1..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_random.py +++ /dev/null @@ -1,75 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_re.py b/env/lib/python3.8/site-packages/astroid/brain/brain_re.py deleted file mode 100644 index c7ee51a5..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_re.py +++ /dev/null @@ -1,36 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_responses.py b/env/lib/python3.8/site-packages/astroid/brain/brain_responses.py deleted file mode 100644 index 3a441298..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_responses.py +++ /dev/null @@ -1,73 +0,0 @@ -""" -Astroid hooks for responses. - -It might need to be manually updated from the public methods of -:class:`responses.RequestsMock`. - -See: https://github.com/getsentry/responses/blob/master/responses.py - -""" -import astroid - - -def responses_funcs(): - return astroid.parse( - """ - DELETE = "DELETE" - GET = "GET" - HEAD = "HEAD" - OPTIONS = "OPTIONS" - PATCH = "PATCH" - POST = "POST" - PUT = "PUT" - response_callback = None - - def reset(): - return - - def add( - method=None, # method or ``Response`` - url=None, - body="", - adding_headers=None, - *args, - **kwargs - ): - return - - def add_passthru(prefix): - return - - def remove(method_or_response=None, url=None): - return - - def replace(method_or_response=None, url=None, body="", *args, **kwargs): - return - - def add_callback( - method, url, callback, match_querystring=False, content_type="text/plain" - ): - return - - calls = [] - - def __enter__(): - return - - def __exit__(type, value, traceback): - success = type is None - return success - - def activate(func): - return func - - def start(): - return - - def stop(allow_assert=True): - return - """ - ) - - -astroid.register_module_extender(astroid.MANAGER, "responses", responses_funcs) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_scipy_signal.py b/env/lib/python3.8/site-packages/astroid/brain/brain_scipy_signal.py deleted file mode 100644 index 996300d4..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_scipy_signal.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2019 Valentin Valls - -# 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 scipy.signal module.""" - -import astroid - - -def scipy_signal(): - return astroid.parse( - """ - # different functions defined in scipy.signals - - def barthann(M, sym=True): - return numpy.ndarray([0]) - - def bartlett(M, sym=True): - return numpy.ndarray([0]) - - def blackman(M, sym=True): - return numpy.ndarray([0]) - - def blackmanharris(M, sym=True): - return numpy.ndarray([0]) - - def bohman(M, sym=True): - return numpy.ndarray([0]) - - def boxcar(M, sym=True): - return numpy.ndarray([0]) - - def chebwin(M, at, sym=True): - return numpy.ndarray([0]) - - def cosine(M, sym=True): - return numpy.ndarray([0]) - - def exponential(M, center=None, tau=1.0, sym=True): - return numpy.ndarray([0]) - - def flattop(M, sym=True): - return numpy.ndarray([0]) - - def gaussian(M, std, sym=True): - return numpy.ndarray([0]) - - def general_gaussian(M, p, sig, sym=True): - return numpy.ndarray([0]) - - def hamming(M, sym=True): - return numpy.ndarray([0]) - - def hann(M, sym=True): - return numpy.ndarray([0]) - - def hanning(M, sym=True): - return numpy.ndarray([0]) - - def impulse2(system, X0=None, T=None, N=None, **kwargs): - return numpy.ndarray([0]), numpy.ndarray([0]) - - def kaiser(M, beta, sym=True): - return numpy.ndarray([0]) - - def nuttall(M, sym=True): - return numpy.ndarray([0]) - - def parzen(M, sym=True): - return numpy.ndarray([0]) - - def slepian(M, width, sym=True): - return numpy.ndarray([0]) - - def step2(system, X0=None, T=None, N=None, **kwargs): - return numpy.ndarray([0]), numpy.ndarray([0]) - - def triang(M, sym=True): - return numpy.ndarray([0]) - - def tukey(M, alpha=0.5, sym=True): - return numpy.ndarray([0]) - """ - ) - - -astroid.register_module_extender(astroid.MANAGER, "scipy.signal", scipy_signal) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_six.py b/env/lib/python3.8/site-packages/astroid/brain/brain_six.py deleted file mode 100644 index 46d9fa32..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_six.py +++ /dev/null @@ -1,201 +0,0 @@ -# Copyright (c) 2014-2016, 2018, 2020 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 importlib import reload -reload_module = lambda module: 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/env/lib/python3.8/site-packages/astroid/brain/brain_ssl.py b/env/lib/python3.8/site-packages/astroid/brain/brain_ssl.py deleted file mode 100644 index 2ae21c35..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_ssl.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2016, 2018 Claudiu Popa -# Copyright (c) 2016 Ceridwen -# Copyright (c) 2019 Benjamin Elven <25181435+S3ntinelX@users.noreply.github.com> - -# 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/env/lib/python3.8/site-packages/astroid/brain/brain_subprocess.py b/env/lib/python3.8/site-packages/astroid/brain/brain_subprocess.py deleted file mode 100644 index ab7d5d7e..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_subprocess.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright (c) 2016-2020 Claudiu Popa -# Copyright (c) 2017 Hugo -# Copyright (c) 2018 Peter Talley -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2019 Hugo van Kemenade - -# 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 astroid - - -PY37 = sys.version_info >= (3, 7) -PY36 = sys.version_info >= (3, 6) - - -def _subprocess_transform(): - 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 - """ - wait_signature = "def wait(self, timeout=None)" - ctx_manager = """ - def __enter__(self): return self - def __exit__(self, *args): pass - """ - py3_args = "args = []" - - if PY37: - check_output_signature = """ - check_output( - args, *, - stdin=None, - stderr=None, - shell=False, - cwd=None, - encoding=None, - errors=None, - universal_newlines=False, - timeout=None, - env=None, - text=None, - restore_signals=True, - preexec_fn=None, - pass_fds=(), - input=None, - start_new_session=False - ): - """.strip() - else: - check_output_signature = """ - check_output( - args, *, - stdin=None, - stderr=None, - shell=False, - cwd=None, - encoding=None, - errors=None, - universal_newlines=False, - timeout=None, - env=None, - restore_signals=True, - preexec_fn=None, - pass_fds=(), - input=None, - start_new_session=False - ): - """.strip() - - code = textwrap.dedent( - """ - def %(check_output_signature)s - if universal_newlines: - return "" - return b"" - - 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 - """ - % { - "check_output_signature": check_output_signature, - "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/env/lib/python3.8/site-packages/astroid/brain/brain_threading.py b/env/lib/python3.8/site-packages/astroid/brain/brain_threading.py deleted file mode 100644 index ba3085b5..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_threading.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2016, 2018-2019 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): - return False - def release(self): - pass - def __enter__(self): - return True - def __exit__(self, *args): - pass - def locked(self): - return False - - def Lock(): - return lock() - """ - ) - - -astroid.register_module_extender(astroid.MANAGER, "threading", _thread_transform) diff --git a/env/lib/python3.8/site-packages/astroid/brain/brain_typing.py b/env/lib/python3.8/site-packages/astroid/brain/brain_typing.py deleted file mode 100644 index 9ff72274..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_typing.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- 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/env/lib/python3.8/site-packages/astroid/brain/brain_uuid.py b/env/lib/python3.8/site-packages/astroid/brain/brain_uuid.py deleted file mode 100644 index 5a33fc25..00000000 --- a/env/lib/python3.8/site-packages/astroid/brain/brain_uuid.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2017-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 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/env/lib/python3.8/site-packages/astroid/builder.py b/env/lib/python3.8/site-packages/astroid/builder.py deleted file mode 100644 index 142764b1..00000000 --- a/env/lib/python3.8/site-packages/astroid/builder.py +++ /dev/null @@ -1,455 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2013 Phil Schaf -# Copyright (c) 2014-2019 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 get_parser_module -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 - -objects = util.lazy_import("objects") - -# 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 = "#@" -MISPLACED_TYPE_ANNOTATION_ERROR = "misplaced type annotation" -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().__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, parser_module = _parse_string(data, type_comments=True) - 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, parser_module) - 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: - cls = inferred.__class__ - if cls is bases.Instance or cls is objects.ExceptionInstance: - inferred = inferred._proxied - iattrs = inferred.instance_attrs - if not _can_assign_attr(inferred, node.attrname): - continue - elif isinstance(inferred, bases.Instance): - # Const, Tuple or other containers that inherit from - # `Instance` - 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 - - -def _parse_string(data, type_comments=True): - parser_module = get_parser_module(type_comments=type_comments) - try: - parsed = parser_module.parse(data + "\n", type_comments=type_comments) - except SyntaxError as exc: - # If the type annotations are misplaced for some reason, we do not want - # to fail the entire parsing of the file, so we need to retry the parsing without - # type comment support. - if exc.args[0] != MISPLACED_TYPE_ANNOTATION_ERROR or not type_comments: - raise - - parser_module = get_parser_module(type_comments=False) - parsed = parser_module.parse(data + "\n", type_comments=False) - return parsed, parser_module diff --git a/env/lib/python3.8/site-packages/astroid/context.py b/env/lib/python3.8/site-packages/astroid/context.py deleted file mode 100644 index 40cebf22..00000000 --- a/env/lib/python3.8/site-packages/astroid/context.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright (c) 2015-2016, 2018-2019 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/env/lib/python3.8/site-packages/astroid/decorators.py b/env/lib/python3.8/site-packages/astroid/decorators.py deleted file mode 100644 index 0f3632c4..00000000 --- a/env/lib/python3.8/site-packages/astroid/decorators.py +++ /dev/null @@ -1,142 +0,0 @@ -# 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 Tomas Gavenciak -# 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/env/lib/python3.8/site-packages/astroid/exceptions.py b/env/lib/python3.8/site-packages/astroid/exceptions.py deleted file mode 100644 index 08e72c13..00000000 --- a/env/lib/python3.8/site-packages/astroid/exceptions.py +++ /dev/null @@ -1,230 +0,0 @@ -# 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().__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().__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().__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().__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().__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().__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().__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/env/lib/python3.8/site-packages/astroid/helpers.py b/env/lib/python3.8/site-packages/astroid/helpers.py deleted file mode 100644 index 1c84651d..00000000 --- a/env/lib/python3.8/site-packages/astroid/helpers.py +++ /dev/null @@ -1,282 +0,0 @@ -# Copyright (c) 2015-2020 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(context=context) - 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 *type2*.""" - return _type_check(type1=type2, 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 - """ - # pylint: disable=import-outside-toplevel; circular import - 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) - - node_type = object_type(inferred_node, context=context) - if not node_type: - raise exceptions.InferenceError(node=node) - - try: - len_call = next(node_type.igetattr("__len__", context=context)) - except exceptions.AttributeInferenceError: - raise exceptions.AstroidTypeError( - "object of type '{}' has no len()".format(node_type.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 - if isinstance(result_of_len, bases.Instance) and result_of_len.is_subtype_of( - "builtins.int" - ): - # Fake a result as we don't know the arguments of the instance call. - return 0 - raise exceptions.AstroidTypeError( - "'{}' object cannot be interpreted as an integer".format(result_of_len) - ) diff --git a/env/lib/python3.8/site-packages/astroid/inference.py b/env/lib/python3.8/site-packages/astroid/inference.py deleted file mode 100644 index bc3e1f97..00000000 --- a/env/lib/python3.8/site-packages/astroid/inference.py +++ /dev/null @@ -1,994 +0,0 @@ -# -*- 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-2020 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-2019 Nick Drozd -# Copyright (c) 2018 Daniel Martin -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2018 Ashley Whetter -# Copyright (c) 2018 HoverHell -# Copyright (c) 2020 Leandro T. C. Melo - -# 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 - -import wrapt -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() -# Prevents circular imports -objects = util.lazy_import("objects") - - -# .infer method ############################################################### - - -def infer_end(self, context=None): - """Inference's end for nodes that yield themselves on inference - - These are objects for which inference does not have any semantic, - such as Module or Consts. - """ - yield self - - -nodes.Module._infer = infer_end -nodes.ClassDef._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)) - elif isinstance(elt, nodes.NamedExpr): - value = helpers.safe_infer(elt.value, context) - if not value: - raise exceptions.InferenceError(node=node, context=context) - values.append(value) - else: - values.append(elt) - return values - - -@decorators.raise_if_nothing_inferred -def infer_sequence(self, context=None): - has_starred_named_expr = any( - isinstance(e, (nodes.Starred, nodes.NamedExpr)) for e in self.elts - ) - if has_starred_named_expr: - 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 - else: - yield self - - -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 - elif not context: - context = contextmod.InferenceContext() - - try: - context.boundnode = owner - yield from owner.igetattr(self.attrname, context) - except ( - exceptions.AttributeInferenceError, - exceptions.InferenceError, - AttributeError, - ): - pass - finally: - 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() - - -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 - elif 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.raise_if_nothing_inferred( - decorators.path_wrapper(infer_subscript) -) -nodes.Subscript.infer_lhs = decorators.raise_if_nothing_inferred(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 - """ - if isinstance(self.parent, nodes.AugAssign): - return self.parent.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 - - -@decorators.raise_if_nothing_inferred -def infer_ifexp(self, context=None): - """Support IfExp inference - - If we can't infer the truthiness of the condition, we default - to inferring both branches. Otherwise, we infer either branch - depending on the condition. - """ - both_branches = False - # We use two separate contexts for evaluating lhs and rhs because - # 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) - try: - test = next(self.test.infer(context=context.clone())) - except exceptions.InferenceError: - both_branches = True - else: - if test is not util.Uninferable: - if test.bool_value(): - yield from self.body.infer(context=lhs_context) - else: - yield from self.orelse.infer(context=rhs_context) - else: - both_branches = True - if both_branches: - yield from self.body.infer(context=lhs_context) - yield from self.orelse.infer(context=rhs_context) - - -nodes.IfExp._infer = infer_ifexp - - -# pylint: disable=dangerous-default-value -@wrapt.decorator -def _cached_generator(func, instance, args, kwargs, _cache={}): - node = args[0] - try: - return iter(_cache[func, id(node)]) - except KeyError: - result = func(*args, **kwargs) - # Need to keep an iterator around - original, copy = itertools.tee(result) - _cache[func, id(node)] = list(copy) - return original - - -# When inferring a property, we instantiate a new `objects.Property` object, -# which in turn, because it inherits from `FunctionDef`, sets itself in the locals -# of the wrapping frame. This means that everytime we infer a property, the locals -# are mutated with a new instance of the property. This is why we cache the result -# of the function's inference. -@_cached_generator -def infer_functiondef(self, context=None): - if not self.decorators or not bases._is_property(self): - yield self - return dict(node=self, context=context) - - prop_func = objects.Property( - function=self, - name=self.name, - doc=self.doc, - lineno=self.lineno, - parent=self.parent, - col_offset=self.col_offset, - ) - prop_func.postinit(body=[], args=self.args) - yield prop_func - return dict(node=self, context=context) - - -nodes.FunctionDef._infer = infer_functiondef diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/__init__.py b/env/lib/python3.8/site-packages/astroid/interpreter/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 6b4ac5c43af30c27ba58dc59dd127ad6c7609022..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmYk0F%H5o3`J9k0U`Au46O&24hV6AE{Hh_t<^@fPL#NndJ@jSH8=(Kz4-CS=Ir)i!hM| zZyN4#G*m@Sh>ON**KH_M@o<6dynsZ@AJ={PDt?F{o}9x zUO>n{_T$Zm;p2OVUdNDnQbx5Ue3nemPbkIr;X=i%TJqW3v(k4(l+L1 z8m3n;w^H_)beG~kDIpJJVdAXNJeR{P;RC6-5=LcWKP!e@PehW%IUfr%lBw>6;pQmQ zJR47PF%~#!GFk9c3e5{?a56vOP?(W`((u^8(oSgvkCQ}b9XcmB;iW86o)vt1yEhcD zV$@0(?|jo9%mxFYM3D%-Bg|9?XHN@mrZR+cGm6d31B?juIyN3FflJ6ek@9I~MsABa zm_=9AWNRa1s`PaJ(k!V@5s`bg7Fbth9hGp-$qehCgoW5CNhz-C)F_e^49II zqPx-UZz9}mb#j1Y6sy_lRF-+VnrC}r)yP#XMAQxMYp%;=bkn)F;gl1XRGX3u+2puP zoR~7sku~jds_gBG@Ur~%!hcbHveBh=D4r%_V$-h^i;dS$120X82hmS3RAiSN(-&k& zPS_zcY}Y&XeyH2FX=itq9^pwGfl&ey^2-d2|J>Pe&y?*OlvoI0ZVD) zCHsw5KG4(LNPwQR$A(~C-+|~4F;wK2YlpO=3+GP=CBL$i;4t0jvbveeB+hm10Ri}A zy<2q0EeDvK&pw{->1RcMtYq)r><(+av;CW>O;d@aRQi@BeY@N87MjKTXnpX3!I-PMAv?vA#$7N`rZ4l`|4paZnYwsqdJgXNog`TT|6flgn=KAA zGP%)RuEBI*Wn=4Kx8_!B{}E!U8=EEQw{C#C@#U{)iK)HE!qji|cgid`z~&6eb?|U* z!j-QM9^|ps>taxM`iXs=?{lb9w)S17u48flnnA_k#X$xAYT4`)tm|tSNQ_PbGP-`<#@|ou z0$xPwZq)VO2-h0F5VQIWy00PHb_AgTe!#NTULNG9Se=n(MQ5a0G5qU*I2U17z_I!Q z8@v9ZofpBKi|c)CyBL>E;&+gFT+6c_v)XP@xBC55CjGv$ji@Y{&Mey&bP0ABPnfvR=mEhXD)dk{5J>w}aq+H#$5b diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-38.pyc deleted file mode 100644 index dbb5d751e4aae5fd38b78b252f34f2d5f8b3de65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26957 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̍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 diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-38.pyc deleted file mode 100644 index 30a876fcf4e8e261f91c91ae63426333ff19ae44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9411 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 RmrQpY4B?cHxJTTP{{hnRs-pk^ diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-38.pyc b/env/lib/python3.8/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-38.pyc deleted file mode 100644 index 49ecb0d859de1929e124310b51b5c6b24fb67ccb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmYjNu}%Xq40Y~GX-kU`EPMdV4Q(V?Iv|9E7+AU>1avta7po0-mz`9umvcJ z9vuk?M~NxigNg1yMJj%QX{5w8B&|=@!6X+U{94E(_6v5m&)`8p(Y1TeoIQ%7%{nnj zqGnJRvy{-;1?A|b2dT*_baj?v%1~r8bctxTE2~1`4XDM9oh;-wQHxo~%|<8;?|TPu8Tmsx5iB z@VXq;tER8r|8U)~S6C1PwHcF`0&8}z)}l)yOY6dV-VN9aw>qc1&!WV$n3)UzABn!$ H6}|We;mm1U diff --git a/env/lib/python3.8/site-packages/astroid/interpreter/_import/spec.py b/env/lib/python3.8/site-packages/astroid/interpreter/_import/spec.py deleted file mode 100644 index 3cf5fea5..00000000 --- a/env/lib/python3.8/site-packages/astroid/interpreter/_import/spec.py +++ /dev/null @@ -1,346 +0,0 @@ -# Copyright (c) 2016-2018 Claudiu Popa -# 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 -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 Ashley Whetter - -import abc -import collections -import distutils -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)) - ] - # We already import distutils elsewhere in astroid, - # so if it is the same module, we can use it directly. - elif spec.name == "distutils" and spec.location in distutils.__path__: - # distutils is patched inside virtualenvs to pick up submodules - # from the original Python, not from the virtualenv itself. - path = list(distutils.__path__) - 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().__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: - _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/env/lib/python3.8/site-packages/astroid/interpreter/_import/util.py b/env/lib/python3.8/site-packages/astroid/interpreter/_import/util.py deleted file mode 100644 index a917bd3d..00000000 --- a/env/lib/python3.8/site-packages/astroid/interpreter/_import/util.py +++ /dev/null @@ -1,10 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/interpreter/dunder_lookup.py b/env/lib/python3.8/site-packages/astroid/interpreter/dunder_lookup.py deleted file mode 100644 index 0ae9bc90..00000000 --- a/env/lib/python3.8/site-packages/astroid/interpreter/dunder_lookup.py +++ /dev/null @@ -1,66 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/interpreter/objectmodel.py b/env/lib/python3.8/site-packages/astroid/interpreter/objectmodel.py deleted file mode 100644 index 277c8250..00000000 --- a/env/lib/python3.8/site-packages/astroid/interpreter/objectmodel.py +++ /dev/null @@ -1,801 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2016-2019 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 Ville Skyttä -# 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), - zip(args.posonlyargs or [], args.posonlyargs_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): - # pylint: disable=import-outside-toplevel; circular import - 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 or len(caller.args) < 1: - 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, - ) - # 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 - positional_or_keyword_params = func.args.args.copy() - positional_or_keyword_params.append(astroid.AssignName(name="type")) - - positional_only_params = func.args.posonlyargs.copy() - - arguments = astroid.Arguments(parent=func.args.parent) - arguments.postinit( - args=positional_or_keyword_params, - posonlyargs=positional_only_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" - ) - - # pylint: disable=import-outside-toplevel; circular import - 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): - # pylint: disable=import-outside-toplevel; circular import - 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. - """ - # pylint: disable=import-outside-toplevel; circular import - 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): - # pylint: disable=import-outside-toplevel; circular import - 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) - - # pylint: disable=import-outside-toplevel; circular import - 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) - - # pylint: disable=import-outside-toplevel; circular import - 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) - - # pylint: disable=import-outside-toplevel; circular import - from astroid import objects - - obj = objects.DictValues(obj) - return self._generic_dict_attribute(obj, "values") - - -class PropertyModel(ObjectModel): - """Model for a builtin property""" - - # pylint: disable=import-outside-toplevel - def _init_function(self, name): - from astroid.node_classes import Arguments - from astroid.scoped_nodes import FunctionDef - - args = Arguments() - args.postinit( - args=[], - defaults=[], - kwonlyargs=[], - kw_defaults=[], - annotations=[], - posonlyargs=[], - posonlyargs_annotations=[], - kwonlyargs_annotations=[], - ) - - function = FunctionDef(name=name, parent=self._instance) - - function.postinit(args=args, body=[]) - return function - - @property - def attr_fget(self): - from astroid.scoped_nodes import FunctionDef - - func = self._instance - - class PropertyFuncAccessor(FunctionDef): - def infer_call_result(self, caller=None, context=None): - nonlocal func - if caller and len(caller.args) != 1: - raise exceptions.InferenceError( - "fget() needs a single argument", target=self, context=context - ) - - yield from func.function.infer_call_result( - caller=caller, context=context - ) - - property_accessor = PropertyFuncAccessor(name="fget", parent=self._instance) - property_accessor.postinit(args=func.args, body=func.body) - return property_accessor - - @property - def attr_setter(self): - return self._init_function("setter") - - @property - def attr_deleter(self): - return self._init_function("deleter") - - @property - def attr_getter(self): - return self._init_function("getter") - - # pylint: enable=import-outside-toplevel diff --git a/env/lib/python3.8/site-packages/astroid/manager.py b/env/lib/python3.8/site-packages/astroid/manager.py deleted file mode 100644 index 82208adf..00000000 --- a/env/lib/python3.8/site-packages/astroid/manager.py +++ /dev/null @@ -1,350 +0,0 @@ -# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014-2019 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 -# Copyright (c) 2019 Raphael Gaschignard -# Copyright (c) 2020 Anubhav <35621759+anubh-v@users.noreply.github.com> -# Copyright (c) 2020 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 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 - - -ZIP_IMPORT_EXTS = (".zip", ".egg", ".whl") - - -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: - # pylint: disable=import-outside-toplevel; circular import - 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 ast_from_string(self, data, modname="", filepath=None): - """ Given some source code as a string, return its corresponding astroid object""" - # pylint: disable=import-outside-toplevel; circular import - from astroid.builder import AstroidBuilder - - return AstroidBuilder(self).string_build(data, modname, filepath) - - def _build_stub_module(self, modname): - # pylint: disable=import-outside-toplevel; circular import - from astroid.builder import AstroidBuilder - - return AstroidBuilder(self).string_build("", modname) - - def _build_namespace_module(self, modname, path): - # pylint: disable=import-outside-toplevel; circular import - 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) - if context_file: - old_cwd = os.getcwd() - 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 - ) - elif found_spec.type == spec.ModuleType.PY_FROZEN: - return self._build_stub_module(modname) - - 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: - if context_file: - os.chdir(old_cwd) - - def zip_import_data(self, filepath): - if zipimport is None: - return None - - # pylint: disable=import-outside-toplevel; circular import - from astroid.builder import AstroidBuilder - - builder = AstroidBuilder(self) - for ext in ZIP_IMPORT_EXTS: - 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 - - # pylint: disable=import-outside-toplevel; circular import - 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. - """ - from astroid import raw_building # pylint: disable=import-outside-toplevel - - 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/env/lib/python3.8/site-packages/astroid/mixins.py b/env/lib/python3.8/site-packages/astroid/mixins.py deleted file mode 100644 index 497a8400..00000000 --- a/env/lib/python3.8/site-packages/astroid/mixins.py +++ /dev/null @@ -1,160 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/modutils.py b/env/lib/python3.8/site-packages/astroid/modutils.py deleted file mode 100644 index 4e6ed86b..00000000 --- a/env/lib/python3.8/site-packages/astroid/modutils.py +++ /dev/null @@ -1,690 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014-2018, 2020 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 Ville Skyttä -# Copyright (c) 2018 Mario Corchero -# Copyright (c) 2018 Mario Corchero -# Copyright (c) 2018 Anthony Sottile -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 markmcclain -# Copyright (c) 2019 BasPH - -# 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 typing import Optional, List - -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_DIRS = {get_python_lib(), get_python_lib(True)} -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: - 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: Optional[List[str]] = 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 '.' - - :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: str, path: Optional[List[str]] = None, use_sys=True -): - """Load a Python module from it's path. - - :type filepath: str - :param filepath: path to the python module or package - - :param Optional[List[str]] 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) - 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, path=None, is_package_cb=None): - filename = os.path.expanduser(_path_from_filename(filename)) - for pathname in itertools.chain( - path or [], map(_canonicalize_path, sys.path), sys.path - ): - pathname = _cache_normalize_path(pathname) - if not pathname: - continue - modpath = _get_relative_base_path(filename, pathname) - if not modpath: - continue - if is_package_cb(pathname, modpath[:-1]): - return modpath - - raise ImportError( - "Unable to find module for %s in %s" % (filename, ", \n".join(sys.path)) - ) - - -def modpath_from_file(filename, path=None): - """Get the corresponding split module's name from a filename - - This function will return the 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 Optional[List[str]] path: - Optional list of path where the module or package should be - searched (use sys.path if nothing or None is given) - - :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, path, 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) - for path in EXT_LIB_DIRS: - if filename.startswith(_cache_normalize_path(path)): - 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 - """ - return filename.endswith((".py", ".so", ".pyd", ".pyw")) - - -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/env/lib/python3.8/site-packages/astroid/node_classes.py b/env/lib/python3.8/site-packages/astroid/node_classes.py deleted file mode 100644 index 621dc5f2..00000000 --- a/env/lib/python3.8/site-packages/astroid/node_classes.py +++ /dev/null @@ -1,4862 +0,0 @@ -# -*- 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-2020 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-2020 Ashley Whetter -# Copyright (c) 2017, 2019 Łukasz Rogalski -# Copyright (c) 2017 rr- -# Copyright (c) 2018-2019 hippo91 -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2018 brendanator -# Copyright (c) 2018 HoverHell -# Copyright (c) 2019 kavins14 -# Copyright (c) 2019 kavins14 - -# 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 -import sys -from functools import lru_cache, 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() -PY38 = sys.version_info[:2] >= (3, 8) - - -def _is_const(value): - return isinstance(value, tuple(CONST_CLS)) - - -@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 - """ - if self.parent: - return self.parent.scope() - return None - - 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() - - # 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 types. - - :param klass: The types of node to search for. - :type klass: builtins.type or tuple(builtins.type) - - :param skip_klass: The types of node to ignore. This is useful to ignore - subclasses of :attr:`klass`. - :type skip_klass: builtins.type or tuple(builtins.type) - - :returns: The node of the given types. - :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, context=None): - """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().__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_elements(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) if _is_const(e) else 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, context=None): - """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 - - if isinstance(assign_type, NamedExpr): - _stmts = [node] - 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().__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().__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().__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. - # pylint: disable=too-many-instance-attributes - _astroid_fields = ( - "args", - "defaults", - "kwonlyargs", - "posonlyargs", - "posonlyargs_annotations", - "kw_defaults", - "annotations", - "varargannotation", - "kwargannotation", - "kwonlyargs_annotations", - "type_comment_args", - "type_comment_kwonlyargs", - "type_comment_posonlyargs", - ) - 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().__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.posonlyargs = [] - """The arguments that can only 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.posonlyargs_annotations = [] - """The type annotations of arguments that can only be passed positionally. - - :type: list(NodeNG) - """ - - self.kwonlyargs_annotations = [] - """The type annotations of arguments that cannot be passed positionally. - - :type: list(NodeNG) - """ - - self.type_comment_args = [] - """The type annotation, passed by a type comment, of each argument. - - If an argument does not have a type comment, - the value for that argument will be None. - - :type: list(NodeNG or None) - """ - - self.type_comment_kwonlyargs = [] - """The type annotation, passed by a type comment, of each keyword only argument. - - If an argument does not have a type comment, - the value for that argument will be None. - - :type: list(NodeNG or None) - """ - - self.type_comment_posonlyargs = [] - """The type annotation, passed by a type comment, of each positional argument. - - If an argument does not have a type comment, - the value for that argument will be None. - - :type: list(NodeNG or None) - """ - - # pylint: disable=too-many-arguments - def postinit( - self, - args, - defaults, - kwonlyargs, - kw_defaults, - annotations, - posonlyargs=None, - kwonlyargs_annotations=None, - posonlyargs_annotations=None, - varargannotation=None, - kwargannotation=None, - type_comment_args=None, - type_comment_kwonlyargs=None, - type_comment_posonlyargs=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 posonlyargs: The arguments that can only 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 posonlyargs_annotations: The type annotations of arguments that - can only be passed positionally. This should always be passed in - Python 3. - :type posonlyargs_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 - - :param type_comment_args: The type annotation, - passed by a type comment, of each argument. - :type type_comment_args: list(NodeNG or None) - - :param type_comment_args: The type annotation, - passed by a type comment, of each keyword only argument. - :type type_comment_args: list(NodeNG or None) - - :param type_comment_args: The type annotation, - passed by a type comment, of each positional argument. - :type type_comment_args: list(NodeNG or None) - """ - self.args = args - self.defaults = defaults - self.kwonlyargs = kwonlyargs - self.posonlyargs = posonlyargs - self.kw_defaults = kw_defaults - self.annotations = annotations - self.kwonlyargs_annotations = kwonlyargs_annotations - self.posonlyargs_annotations = posonlyargs_annotations - self.varargannotation = varargannotation - self.kwargannotation = kwargannotation - self.type_comment_args = type_comment_args - self.type_comment_kwonlyargs = type_comment_kwonlyargs - self.type_comment_posonlyargs = type_comment_posonlyargs - - # pylint: disable=too-many-arguments - - 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().fromlineno - return max(lineno, self.parent.fromlineno or 0) - - @decorators.cachedproperty - def arguments(self): - """Get all the arguments for this node, including positional only and positional and keyword""" - return list(itertools.chain((self.posonlyargs or ()), self.args or ())) - - def format_args(self): - """Get the arguments formatted as string. - - :returns: The formatted arguments. - :rtype: str - """ - result = [] - positional_only_defaults = [] - positional_or_keyword_defaults = self.defaults - if self.defaults: - args = self.args or [] - positional_or_keyword_defaults = self.defaults[-len(args) :] - positional_only_defaults = self.defaults[: len(self.defaults) - len(args)] - - if self.posonlyargs: - result.append( - _format_args( - self.posonlyargs, - positional_only_defaults, - self.posonlyargs_annotations, - ) - ) - result.append("/") - if self.args: - result.append( - _format_args( - self.args, - positional_or_keyword_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. - """ - args = self.arguments - index = _find_arg(argname, args)[0] - if index is not None: - idx = index - (len(args) - len(self.defaults)) - if idx >= 0: - return self.defaults[idx] - index = _find_arg(argname, self.kwonlyargs)[0] - if index is not None and self.kw_defaults[index] is not None: - return self.kw_defaults[index] - 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, rec=True)[1] is not None - or self.kwonlyargs - and _find_arg(name, self.kwonlyargs, rec=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.arguments: - return _find_arg(argname, self.arguments, rec) - return None, None - - def get_children(self): - yield from self.posonlyargs or () - - for elt in self.posonlyargs_annotations: - if elt is not None: - yield elt - - 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 - default_sep = "=" - if annotation is not None: - argname += ": " + annotation.as_string() - default_sep = " = " - values.append(argname) - - if defaults is not None and i >= default_offset: - if defaults[i - default_offset] is not None: - values[-1] += default_sep + 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().__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().__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().__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().__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().__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().__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(Const) - - :raises TypeError: If this node does not represent something that is iterable. - """ - if isinstance(self.value, str): - return [const_factory(elem) for elem in self.value] - raise TypeError("Cannot iterate over type {!r}".format(type(self.value))) - - 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, context=None): - """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().__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().__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_elements(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) if _is_const(v) else v) - for k, v in items.items() - # The keys need to be constants - if _is_const(k) - ] - 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, context=None): - """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, context=None): - """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().__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().__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().__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().__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().__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().__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().__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().__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().__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().__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().__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().__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 - - def _get_yield_nodes_skip_lambdas(self): - """A While node can contain a Yield node in the test""" - yield from self.test._get_yield_nodes_skip_lambdas() - yield from super()._get_yield_nodes_skip_lambdas() - - -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 NamedExpr(mixins.AssignTypeMixin, NodeNG): - """Represents the assignment from the assignment expression - - >>> module = astroid.parse('if a := 1: pass') - >>> module.body[0].test - - """ - - _astroid_fields = ("target", "value") - target = None - """The assignment target - - :type: Name - """ - value = None - """The value that gets assigned in the expression - - :type: NodeNG - """ - - def postinit(self, target, value): - self.target = target - self.value = value - - -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 - - -class EvaluatedObject(NodeNG): - """Contains an object that has already been inferred - - This class is useful to pre-evaluate a particular node, - with the resulting class acting as the non-evaluated node. - """ - - name = "EvaluatedObject" - _astroid_fields = ("original",) - _other_fields = ("value",) - - original = None - """The original node that has already been evaluated - - :type: NodeNG - """ - - value = None - """The inferred value - - :type: Union[Uninferable, NodeNG] - """ - - def __init__(self, original, value): - self.original = original - self.value = value - super().__init__( - lineno=self.original.lineno, - col_offset=self.original.col_offset, - parent=self.original.parent, - ) - - def infer(self, context=None, **kwargs): - yield self.value - - -# constants ############################################################## - -CONST_CLS = { - list: List, - tuple: Tuple, - dict: Dict, - set: Set, - type(None): Const, - type(NotImplemented): Const, -} -if PY38: - CONST_CLS[type(...)] = 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/env/lib/python3.8/site-packages/astroid/nodes.py b/env/lib/python3.8/site-packages/astroid/nodes.py deleted file mode 100644 index 4ce4ebe2..00000000 --- a/env/lib/python3.8/site-packages/astroid/nodes.py +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (c) 2006-2011, 2013 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2010 Daniel Harding -# Copyright (c) 2014-2020 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, - NamedExpr, - 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, - EvaluatedObject, -) -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, - NamedExpr, - Nonlocal, - Module, - Pass, - Print, - Raise, - Return, - Set, - SetComp, - Slice, - Starred, - Subscript, - TryExcept, - TryFinally, - Tuple, - UnaryOp, - While, - With, - Yield, - YieldFrom, - FormattedValue, - JoinedStr, -) diff --git a/env/lib/python3.8/site-packages/astroid/objects.py b/env/lib/python3.8/site-packages/astroid/objects.py deleted file mode 100644 index fb782e6d..00000000 --- a/env/lib/python3.8/site-packages/astroid/objects.py +++ /dev/null @@ -1,314 +0,0 @@ -# Copyright (c) 2015-2016, 2018-2020 Claudiu Popa -# Copyright (c) 2015-2016 Ceridwen -# Copyright (c) 2015 Florian Bruhin -# Copyright (c) 2016 Derek Gustafson -# Copyright (c) 2018 hippo91 -# 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 isinstance(inferred, Property): - function = inferred.function - try: - yield from function.infer_call_result( - caller=self, context=context - ) - except exceptions.InferenceError: - yield util.Uninferable - 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) - - -class Property(scoped_nodes.FunctionDef): - """Class representing a Python property""" - - def __init__( - self, function, name=None, doc=None, lineno=None, col_offset=None, parent=None - ): - self.function = function - super().__init__(name, doc, lineno, col_offset, parent) - - # pylint: disable=unnecessary-lambda - special_attributes = util.lazy_descriptor(lambda: objectmodel.PropertyModel()) - type = "property" - - def pytype(self): - return "%s.property" % BUILTINS - - def infer_call_result(self, caller=None, context=None): - raise exceptions.InferenceError("Properties are not callable") - - def infer(self, context=None, **kwargs): - return iter((self,)) diff --git a/env/lib/python3.8/site-packages/astroid/protocols.py b/env/lib/python3.8/site-packages/astroid/protocols.py deleted file mode 100644 index 2cdf5548..00000000 --- a/env/lib/python3.8/site-packages/astroid/protocols.py +++ /dev/null @@ -1,780 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014-2020 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 Nick Drozd -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2018 HoverHell -# Copyright (c) 2019 Hugo van Kemenade - -# 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 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, - "@": 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.arguments or self.vararg or self.kwarg): - yield util.Uninferable - return - - functype = self.parent.type - # first argument of instance/class method - if ( - self.arguments - and getattr(self.arguments[0], "name", None) == name - and functype != "staticmethod" - ): - 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 context.boundnode and isinstance(context.boundnode, bases.Instance): - cls = context.boundnode._proxied - if is_metaclass or functype == "classmethod": - yield cls - return - if functype == "method": - yield cls.instantiate_class() - 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 - if not self.arguments and self.parent.name == "__init__": - cls = self.parent.parent.scope() - vararg.elts = [cls.instantiate_class()] - 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, context=context) - 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=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) - 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.raise_if_nothing_inferred -def named_expr_assigned_stmts(self, node, context=None, assign_path=None): - """Infer names and other nodes from an assignment expression""" - if self.target == node: - yield from self.value.infer(context=context) - else: - raise exceptions.InferenceError( - "Cannot infer NamedExpr node {node!r}", - node=self, - assign_path=assign_path, - context=context, - ) - - -nodes.NamedExpr.assigned_stmts = named_expr_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 unpacking. - elts = list(elts) - 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/env/lib/python3.8/site-packages/astroid/raw_building.py b/env/lib/python3.8/site-packages/astroid/raw_building.py deleted file mode 100644 index b2612778..00000000 --- a/env/lib/python3.8/site-packages/astroid/raw_building.py +++ /dev/null @@ -1,483 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2012 FELD Boris -# Copyright (c) 2014-2020 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 Ville Skyttä -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2020 Robin Jarry - -# 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 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) -TYPE_NONE = type(None) -TYPE_NOTIMPLEMENTED = type(NotImplemented) -TYPE_ELLIPSIS = type(...) - - -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, posonlyargs=None, defaults=None, doc=None): - """create and initialize an astroid FunctionDef node""" - args, defaults, posonlyargs = args or [], defaults or [], posonlyargs or [] - # first argument is now a list of decorators - func = nodes.FunctionDef(name, doc) - func.args = argsnode = nodes.Arguments() - argsnode.args = [] - argsnode.posonlyargs = [] - for arg in args: - argsnode.args.append(nodes.Name()) - argsnode.args[-1].name = arg - argsnode.args[-1].parent = argsnode - for arg in posonlyargs: - argsnode.posonlyargs.append(nodes.Name()) - argsnode.posonlyargs[-1].name = arg - argsnode.posonlyargs[-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""" - signature = inspect.signature(member) - args = [] - defaults = [] - posonlyargs = [] - for param_name, param in signature.parameters.items(): - if param.kind == inspect.Parameter.POSITIONAL_ONLY: - posonlyargs.append(param_name) - elif param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD: - args.append(param_name) - elif param.kind == inspect.Parameter.VAR_POSITIONAL: - args.append(param_name) - elif param.kind == inspect.Parameter.VAR_KEYWORD: - args.append(param_name) - if param.default is not inspect._empty: - defaults.append(param.default) - func = build_function( - getattr(member, "__name__", None) or localname, - args, - posonlyargs, - 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 TypeError: - 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) - - -def _safe_has_attribute(obj, member): - try: - return hasattr(obj, member) - except Exception: # pylint: disable=broad-except - return False - - -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) - elif _safe_has_attribute(member, "__all__"): - module = build_module(name) - _attach_local_node(node, module, name) - # recursion - self.object_build(module, member) - 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 TypeError: - 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 - elif cls is TYPE_ELLIPSIS: - proxy = build_class("Ellipsis") - 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/env/lib/python3.8/site-packages/astroid/rebuilder.py b/env/lib/python3.8/site-packages/astroid/rebuilder.py deleted file mode 100644 index 3fc1a83f..00000000 --- a/env/lib/python3.8/site-packages/astroid/rebuilder.py +++ /dev/null @@ -1,1010 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2009-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2013-2020 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-2019 Ville Skyttä -# Copyright (c) 2018 Tomas Gavenciak -# Copyright (c) 2018 Serhiy Storchaka -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2018 Bryce Guinta -# Copyright (c) 2019-2020 Ashley Whetter -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 Zbigniew Jędrzejewski-Szmek - -# 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 an _ast tree in -order to get a single Astroid representation -""" - -import sys -from typing import Optional - -import astroid -from astroid._ast import parse_function_type_comment, get_parser_module, ParserModule -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", -} -PY37 = sys.version_info >= (3, 7) -PY38 = sys.version_info >= (3, 8) - - -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, parser_module: Optional[ParserModule] = None): - self._manager = manager - self._global_names = [] - self._import_from_nodes = [] - self._delayed_assattr = [] - self._visit_meths = {} - - if parser_module is None: - self._parser_module = get_parser_module() - else: - self._parser_module = parser_module - self._module = self._parser_module.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._module.Expr): - - first_value = node.body[0].value - if isinstance(first_value, self._module.Str) or ( - PY38 - and isinstance(first_value, self._module.Constant) - and isinstance(first_value.value, str) - ): - doc = first_value.value if PY38 else first_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._parser_module.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_arg(self, node, parent): - """visit an arg node by returning a fresh AssName instance""" - return self.visit_assignname(node, parent, node.arg) - - def visit_arguments(self, node, parent): - """visit an Arguments node by returning a fresh instance of it""" - vararg, kwarg = node.vararg, node.kwarg - newnode = nodes.Arguments( - vararg.arg if vararg else None, kwarg.arg if kwarg else None, 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 - posonlyargs = [] - # change added in 82732 (7c5c678e4164), vararg and kwarg - # are instances of `_ast.arg`, not strings - if vararg: - if node.vararg.annotation: - varargannotation = self.visit(node.vararg.annotation, newnode) - vararg = vararg.arg - if kwarg: - if node.kwarg.annotation: - kwargannotation = self.visit(node.kwarg.annotation, newnode) - kwarg = kwarg.arg - 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 - ] - - posonlyargs_annotations = [] - if PY38: - posonlyargs = [self.visit(child, newnode) for child in node.posonlyargs] - posonlyargs_annotations = [ - self.visit(arg.annotation, newnode) if arg.annotation else None - for arg in node.posonlyargs - ] - type_comment_args = [ - self.check_type_comment(child, parent=newnode) for child in node.args - ] - type_comment_kwonlyargs = [ - self.check_type_comment(child, parent=newnode) for child in node.kwonlyargs - ] - type_comment_posonlyargs = [] - if PY38: - type_comment_posonlyargs = [ - self.check_type_comment(child, parent=newnode) - for child in node.posonlyargs - ] - - newnode.postinit( - args=args, - defaults=defaults, - kwonlyargs=kwonlyargs, - posonlyargs=posonlyargs, - kw_defaults=kw_defaults, - annotations=annotations, - kwonlyargs_annotations=kwonlyargs_annotations, - posonlyargs_annotations=posonlyargs_annotations, - varargannotation=varargannotation, - kwargannotation=kwargannotation, - type_comment_args=type_comment_args, - type_comment_kwonlyargs=type_comment_kwonlyargs, - type_comment_posonlyargs=type_comment_posonlyargs, - ) - # 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, parent): - type_comment = getattr(node, "type_comment", None) - if not type_comment: - return None - - try: - type_comment_ast = self._parser_module.parse(type_comment) - except SyntaxError: - # Invalid type comment, just skip it. - return None - - type_object = self.visit(type_comment_ast.body[0], parent=parent) - 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 - - # 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_assign(self, node, parent): - """visit a Assign node by returning a fresh instance of it""" - newnode = nodes.Assign(node.lineno, node.col_offset, parent) - type_annotation = self.check_type_comment(node, parent=newnode) - 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_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_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._parser_module.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._parser_module.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._parser_module.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=True): - """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 - 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" - ], - ) - 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._parser_module.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 an _ast.FunctionDef node while - # parent is an astroid.nodes.FunctionDef node - if PY38: - # Set the line number of the first decorator for Python 3.8+. - lineno = node.decorator_list[0].lineno - else: - lineno = node.lineno - newnode = nodes.Decorators(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) - 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_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, parent=newnode) - 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) - - lineno = node.lineno - if PY38 and node.decorator_list: - # Python 3.8 sets the line number of a decorated function - # to be the actual line number of the function, but the - # previous versions expected the decorator's line number instead. - # We reset the function's line number to that of the - # first decorator to maintain backward compatibility. - # It's not ideal but this discrepancy was baked into - # the framework for *years*. - lineno = node.decorator_list[0].lineno - - newnode = cls(node.name, doc, lineno, node.col_offset, parent) - if node.decorator_list: - decorators = self.visit_decorators(node, newnode) - else: - decorators = None - if 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 - - 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 - - def visit_namedexpr(self, node, parent): - newnode = nodes.NamedExpr(node.lineno, node.col_offset, parent) - newnode.postinit( - self.visit(node.target, newnode), self.visit(node.value, 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 - - # 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_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_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) - # 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_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_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_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_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_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._parser_module.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, cls, 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, parent=newnode) - 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_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 - - 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 diff --git a/env/lib/python3.8/site-packages/astroid/scoped_nodes.py b/env/lib/python3.8/site-packages/astroid/scoped_nodes.py deleted file mode 100644 index 8561e745..00000000 --- a/env/lib/python3.8/site-packages/astroid/scoped_nodes.py +++ /dev/null @@ -1,2927 +0,0 @@ -# -*- 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-2020 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-2019 Nick Drozd -# Copyright (c) 2018 Ville Skyttä -# Copyright (c) 2018 Anthony Sottile -# Copyright (c) 2018 HoverHell -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 Peter de Blanc - -# 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__") -EXCEPTION_BASE_CLASSES = frozenset({"Exception", "BaseException"}) -objects = util.lazy_import("objects") -BUILTIN_DESCRIPTORS = frozenset( - {"classmethod", "staticmethod", "builtins.classmethod", "builtins.staticmethod"} -) - - -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 clean_duplicates_mro(sequences, cls, context): - for sequence in sequences: - names = [ - (node.lineno, node.qname()) if node.name else None for node in sequence - ] - last_index = dict(map(reversed, enumerate(names))) - if names and names[0] is not None and last_index[names[0]] != 0: - raise exceptions.DuplicateBasesError( - message="Duplicates found in MROs {mros} for {cls!r}.", - mros=sequences, - cls=cls, - context=context, - ) - yield [ - node - for i, (node, name) in enumerate(zip(sequence, names)) - if name is None or last_index[name] == i - ] - - -def function_to_method(n, klass): - if isinstance(n, FunctionDef): - if n.type == "classmethod": - return bases.BoundMethod(n, klass) - if n.type == "property": - return n - 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): - if not name: - raise exceptions.AttributeInferenceError( - target=self, attribute=name, context=context - ) - - 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, context=None): - """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().__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, context=None): - """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().__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, context=None): - """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().__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, context=None): - """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, context=None): - """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().__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" - if isinstance(result, FunctionDef): - if not result.decorators: - return None - # Determine if this function is decorated with one of the builtin descriptors we want. - for decorator in result.decorators.nodes: - if isinstance(decorator, node_classes.Name): - if decorator.name in BUILTIN_DESCRIPTORS: - return decorator.name - if ( - isinstance(decorator, node_classes.Attribute) - and isinstance(decorator.expr, node_classes.Name) - and decorator.expr.name == BUILTINS - and decorator.attrname in BUILTIN_DESCRIPTORS - ): - return decorator.attrname - 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.arguments and self.args.arguments[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().__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.arguments: # maybe None with builtin functions - names = _rec_get_names(self.args.arguments) - 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, context=None): - """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().__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 - - @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 - ): # pylint: disable=invalid-overridden-method,too-many-return-statements - """The function type for this node. - - Possible values are: method, function, staticmethod, classmethod. - - :type: str - """ - 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.Attribute) - and isinstance(node.expr, node_classes.Name) - and node.expr.name == BUILTINS - and node.attrname in BUILTIN_DESCRIPTORS - ): - return node.attrname - - 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 not name: - raise exceptions.AttributeInferenceError( - target=self, attribute=name, context=context - ) - - found_attrs = [] - if name in self.instance_attrs: - found_attrs = self.instance_attrs[name] - if name in self.special_attributes: - found_attrs.append(self.special_attributes.lookup(name)) - if found_attrs: - return found_attrs - 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, context=None): - """Get the qualified names of each of the decorators on this function. - - :param context: - An inference context that can be passed to inference functions - :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(context=context): - 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 bool(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: - if self.body and isinstance(self.body[-1], node_classes.Assert): - yield node_classes.Const(None) - return - - raise exceptions.InferenceError( - "The function does not have any return statements" - ) - - 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, context=None): - """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 - - def scope_lookup(self, node, name, offset=0): - """Lookup where the given name is assigned.""" - if name == "__class__": - # __class__ is an implicit closure reference created by the compiler - # if any methods in a class body refer to either __class__ or super. - # In our case, we want to be able to look it up in the current scope - # when `__class__` is being used. - frame = self.parent.frame() - if isinstance(frame, ClassDef): - return self, [frame] - return super().scope_lookup(node, name, offset) - - -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 - - 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().__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__),) - # __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)): - bases = [] - for base in class_bases.itered(): - inferred = next(base.infer(context=context)) - if inferred: - bases.append( - node_classes.EvaluatedObject(original=base, value=inferred) - ) - result.bases = bases - 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__": - # Call type.__call__ if not set metaclass - # (since type is the default metaclass) - context = contextmod.bind_context_to_node(context, self) - yield from dunder_call.infer_call_result(caller, context) - else: - yield self.instantiate_class() - - 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 - """ - try: - if any(cls.name in EXCEPTION_BASE_CLASSES for cls in self.mro()): - # Subclasses of exceptions can be exception instances - return objects.ExceptionInstance(self) - except exceptions.MroError: - pass - 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. - """ - if not name: - raise exceptions.AttributeInferenceError( - target=self, attribute=name, context=context - ) - - 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 - ) - - # Look for AnnAssigns, which are not attributes in the purest sense. - for value in values: - if isinstance(value, node_classes.AssignName): - stmt = value.statement() - if isinstance(stmt, node_classes.AnnAssign) and stmt.value is None: - 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() - context = contextmod.copy_context(context) - metaclass = self.metaclass(context=context) - 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 isinstance(attr, objects.Property): - yield attr - 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 - - metaclass = self.declared_metaclass(context=context) - try: - attributes = self.getattr(name, context, class_context=class_context) - # If we have more than one attribute, make sure that those starting from - # the second one are from the same scope. This is to account for modifications - # to the attribute happening *after* the attribute's definition (e.g. AugAssigns on lists) - if len(attributes) > 1: - first_attr, attributes = attributes[0], attributes[1:] - first_scope = first_attr.scope() - attributes = [first_attr] + [ - attr - for attr in attributes - if attr.parent and attr.parent.scope() == first_scope - ] - - for inferred in bases._infer_stmts(attributes, 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 - elif isinstance(inferred, objects.Property): - function = inferred.function - if not class_context: - # Through an instance so we can solve the property - yield from function.infer_call_result( - caller=self, context=context - ) - # If we have a metaclass, we're accessing this attribute through - # the class itself, which means we can solve the property - elif metaclass: - # Resolve a property as long as it is not accessed through - # the class itself. - yield from function.infer_call_result( - caller=self, context=context - ) - else: - yield inferred - 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(set(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] - unmerged_mro = list(clean_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, context=None): - """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/env/lib/python3.8/site-packages/astroid/test_utils.py b/env/lib/python3.8/site-packages/astroid/test_utils.py deleted file mode 100644 index e22c7a4f..00000000 --- a/env/lib/python3.8/site-packages/astroid/test_utils.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2013-2014 Google, Inc. -# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2015-2016, 2018-2019 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 - -import pytest - -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(*args, **kwargs): - if minver is not None: - pytest.skip( - "Needs Python > %s. Current version is %s." % (minver, str_version) - ) - elif maxver is not None: - pytest.skip( - "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/env/lib/python3.8/site-packages/astroid/transforms.py b/env/lib/python3.8/site-packages/astroid/transforms.py deleted file mode 100644 index e5506cc6..00000000 --- a/env/lib/python3.8/site-packages/astroid/transforms.py +++ /dev/null @@ -1,90 +0,0 @@ -# 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/env/lib/python3.8/site-packages/astroid/util.py b/env/lib/python3.8/site-packages/astroid/util.py deleted file mode 100644 index 3ab75615..00000000 --- a/env/lib/python3.8/site-packages/astroid/util.py +++ /dev/null @@ -1,164 +0,0 @@ -# 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/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/PKG-INFO b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/PKG-INFO deleted file mode 100644 index c348c838..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/PKG-INFO +++ /dev/null @@ -1,451 +0,0 @@ -Metadata-Version: 1.1 -Name: autopep8 -Version: 1.5.4 -Summary: A tool that automatically formats Python code to conform to the PEP 8 style guide -Home-page: https://github.com/hhatto/autopep8 -Author: Hideo Hattori -Author-email: hhatto.jp@gmail.com -License: Expat License -Description: ======== - autopep8 - ======== - - .. image:: https://img.shields.io/pypi/v/autopep8.svg - :target: https://pypi.org/project/autopep8/ - :alt: PyPI Version - - .. image:: https://github.com/hhatto/autopep8/workflows/Python%20package/badge.svg - :target: https://github.com/hhatto/autopep8/actions - :alt: Build status - - .. image:: https://codecov.io/gh/hhatto/autopep8/branch/master/graph/badge.svg - :target: https://codecov.io/gh/hhatto/autopep8 - :alt: Code Coverage - - autopep8 automatically formats Python code to conform to the `PEP 8`_ style - guide. It uses the pycodestyle_ utility to determine what parts of the code - needs to be formatted. autopep8 is capable of fixing most of the formatting - issues_ that can be reported by pycodestyle. - - .. _PEP 8: https://www.python.org/dev/peps/pep-0008/ - .. _issues: https://pycodestyle.readthedocs.org/en/latest/intro.html#error-codes - - .. contents:: - - - Installation - ============ - - From pip:: - - $ pip install --upgrade autopep8 - - Consider using the ``--user`` option_. - - .. _option: https://pip.pypa.io/en/latest/user_guide/#user-installs - - - Requirements - ============ - - autopep8 requires pycodestyle_. - - .. _pycodestyle: https://github.com/PyCQA/pycodestyle - - - Usage - ===== - - To modify a file in place (with aggressive level 2):: - - $ autopep8 --in-place --aggressive --aggressive - - Before running autopep8. - - .. code-block:: python - - import math, sys; - - def example1(): - ####This is a long comment. This should be wrapped to fit within 72 characters. - some_tuple=( 1,2, 3,'a' ); - some_variable={'long':'Long code lines should be wrapped within 79 characters.', - 'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'], - 'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1, - 20,300,40000,500000000,60000000000000000]}} - return (some_tuple, some_variable) - def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key('')); - class Example3( object ): - def __init__ ( self, bar ): - #Comments should have a space after the hash. - if bar : bar+=1; bar=bar* bar ; return bar - else: - some_string = """ - Indentation in multiline strings should not be touched. - Only actual code should be reindented. - """ - return (sys.path, some_string) - - After running autopep8. - - .. code-block:: python - - import math - import sys - - - def example1(): - # This is a long comment. This should be wrapped to fit within 72 - # characters. - some_tuple = (1, 2, 3, 'a') - some_variable = { - 'long': 'Long code lines should be wrapped within 79 characters.', - 'other': [ - math.pi, - 100, - 200, - 300, - 9876543210, - 'This is a long string that goes on'], - 'more': { - 'inner': 'This whole logical line should be wrapped.', - some_tuple: [ - 1, - 20, - 300, - 40000, - 500000000, - 60000000000000000]}} - return (some_tuple, some_variable) - - - def example2(): return ('' in {'f': 2}) in {'has_key() is deprecated': True} - - - class Example3(object): - def __init__(self, bar): - # Comments should have a space after the hash. - if bar: - bar += 1 - bar = bar * bar - return bar - else: - some_string = """ - Indentation in multiline strings should not be touched. - Only actual code should be reindented. - """ - return (sys.path, some_string) - - Options:: - - usage: autopep8 [-h] [--version] [-v] [-d] [-i] [--global-config filename] - [--ignore-local-config] [-r] [-j n] [-p n] [-a] - [--experimental] [--exclude globs] [--list-fixes] - [--ignore errors] [--select errors] [--max-line-length n] - [--line-range line line] [--hang-closing] [--exit-code] - [files [files ...]] - - Automatically formats Python code to conform to the PEP 8 style guide. - - positional arguments: - files files to format or '-' for standard in - - optional arguments: - -h, --help show this help message and exit - --version show program's version number and exit - -v, --verbose print verbose messages; multiple -v result in more - verbose messages - -d, --diff print the diff for the fixed source - -i, --in-place make changes to files in place - --global-config filename - path to a global pep8 config file; if this file does - not exist then this is ignored (default: - ~/.config/pep8) - --ignore-local-config - don't look for and apply local config files; if not - passed, defaults are updated with any config files in - the project's root directory - -r, --recursive run recursively over directories; must be used with - --in-place or --diff - -j n, --jobs n number of parallel jobs; match CPU count if value is - less than 1 - -p n, --pep8-passes n - maximum number of additional pep8 passes (default: - infinite) - -a, --aggressive enable non-whitespace changes; multiple -a result in - more aggressive changes - --experimental enable experimental fixes - --exclude globs exclude file/directory names that match these comma- - separated globs - --list-fixes list codes for fixes; used by --ignore and --select - --ignore errors do not fix these errors/warnings (default: - E226,E24,W50,W690) - --select errors fix only these errors/warnings (e.g. E4,W) - --max-line-length n set maximum allowed line length (default: 79) - --line-range line line, --range line line - only fix errors found within this inclusive range of - line numbers (e.g. 1 99); line numbers are indexed at - 1 - --hang-closing hang-closing option passed to pycodestyle - --exit-code change to behavior of exit code. default behavior of - return value, 0 is no differences, 1 is error exit. - return 2 when add this option. 2 is exists - differences. - - - Features - ======== - - autopep8 fixes the following issues_ reported by pycodestyle_:: - - E101 - Reindent all lines. - E11 - Fix indentation. - E121 - Fix indentation to be a multiple of four. - E122 - Add absent indentation for hanging indentation. - E123 - Align closing bracket to match opening bracket. - E124 - Align closing bracket to match visual indentation. - E125 - Indent to distinguish line from next logical line. - E126 - Fix over-indented hanging indentation. - E127 - Fix visual indentation. - E128 - Fix visual indentation. - E129 - Fix visual indentation. - E131 - Fix hanging indent for unaligned continuation line. - E133 - Fix missing indentation for closing bracket. - E20 - Remove extraneous whitespace. - E211 - Remove extraneous whitespace. - E22 - Fix extraneous whitespace around keywords. - E224 - Remove extraneous whitespace around operator. - E225 - Fix missing whitespace around operator. - E226 - Fix missing whitespace around arithmetic operator. - E227 - Fix missing whitespace around bitwise/shift operator. - E228 - Fix missing whitespace around modulo operator. - E231 - Add missing whitespace. - E241 - Fix extraneous whitespace around keywords. - E242 - Remove extraneous whitespace around operator. - E251 - Remove whitespace around parameter '=' sign. - E252 - Missing whitespace around parameter equals. - E26 - Fix spacing after comment hash for inline comments. - E265 - Fix spacing after comment hash for block comments. - E266 - Fix too many leading '#' for block comments. - E27 - Fix extraneous whitespace around keywords. - E301 - Add missing blank line. - E302 - Add missing 2 blank lines. - E303 - Remove extra blank lines. - E304 - Remove blank line following function decorator. - E305 - Expected 2 blank lines after end of function or class. - E306 - Expected 1 blank line before a nested definition. - E401 - Put imports on separate lines. - E402 - Fix module level import not at top of file - E501 - Try to make lines fit within --max-line-length characters. - E502 - Remove extraneous escape of newline. - E701 - Put colon-separated compound statement on separate lines. - E70 - Put semicolon-separated compound statement on separate lines. - E711 - Fix comparison with None. - E712 - Fix comparison with boolean. - E713 - Use 'not in' for test for membership. - E714 - Use 'is not' test for object identity. - E721 - Use "isinstance()" instead of comparing types directly. - E722 - Fix bare except. - E731 - Use a def when use do not assign a lambda expression. - W291 - Remove trailing whitespace. - W292 - Add a single newline at the end of the file. - W293 - Remove trailing whitespace on blank line. - W391 - Remove trailing blank lines. - W503 - Fix line break before binary operator. - W504 - Fix line break after binary operator. - W601 - Use "in" rather than "has_key()". - W602 - Fix deprecated form of raising exception. - W603 - Use "!=" instead of "<>" - W604 - Use "repr()" instead of backticks. - W605 - Fix invalid escape sequence 'x'. - W690 - Fix various deprecated code (via lib2to3). - - autopep8 also fixes some issues not found by pycodestyle_. - - - Correct deprecated or non-idiomatic Python code (via ``lib2to3``). Use this - for making Python 2.7 code more compatible with Python 3. (This is triggered - if ``W690`` is enabled.) - - Normalize files with mixed line endings. - - Put a blank line between a class docstring and its first method - declaration. (Enabled with ``E301``.) - - Remove blank lines between a function declaration and its docstring. (Enabled - with ``E303``.) - - autopep8 avoids fixing some issues found by pycodestyle_. - - - ``E112``/``E113`` for non comments are reports of bad indentation that break - syntax rules. These should not be modified at all. - - ``E265``, which refers to spacing after comment hash, is ignored if the - comment looks like code. autopep8 avoids modifying these since they are not - real comments. If you really want to get rid of the pycodestyle_ warning, - consider just removing the commented-out code. (This can be automated via - eradicate_.) - - .. _eradicate: https://github.com/myint/eradicate - - - More advanced usage - =================== - - By default autopep8 only makes whitespace changes. Thus, by default, it does - not fix ``E711`` and ``E712``. (Changing ``x == None`` to ``x is None`` may - change the meaning of the program if ``x`` has its ``__eq__`` method - overridden.) Nor does it correct deprecated code ``W6``. To enable these - more aggressive fixes, use the ``--aggressive`` option:: - - $ autopep8 --aggressive - - Use multiple ``--aggressive`` to increase the aggressiveness level. For - example, ``E712`` requires aggressiveness level 2 (since ``x == True`` could be - changed to either ``x`` or ``x is True``, but autopep8 chooses the former). - - ``--aggressive`` will also shorten lines more aggressively. It will also remove - trailing whitespace more aggressively. (Usually, we don't touch trailing - whitespace in docstrings and other multiline strings. And to do even more - aggressive changes to docstrings, use docformatter_.) - - .. _docformatter: https://github.com/myint/docformatter - - To enable only a subset of the fixes, use the ``--select`` option. For example, - to fix various types of indentation issues:: - - $ autopep8 --select=E1,W1 - - Similarly, to just fix deprecated code:: - - $ autopep8 --aggressive --select=W6 - - The above is useful when trying to port a single code base to work with both - Python 2 and Python 3 at the same time. - - If the file being fixed is large, you may want to enable verbose progress - messages:: - - $ autopep8 -v - - Passing in ``--experimental`` enables the following functionality: - - - Shortens code lines by taking its length into account - - :: - - $ autopep8 --experimental - - Use as a module - =============== - - The simplest way of using autopep8 as a module is via the ``fix_code()`` - function: - - >>> import autopep8 - >>> autopep8.fix_code('x= 123\n') - 'x = 123\n' - - Or with options: - - >>> import autopep8 - >>> autopep8.fix_code('x.has_key(y)\n', - ... options={'aggressive': 1}) - 'y in x\n' - >>> autopep8.fix_code('print( 123 )\n', - ... options={'ignore': ['E']}) - 'print( 123 )\n' - - - Configuration - ============= - - By default, if ``$HOME/.config/pycodestyle`` (``~\.pycodestyle`` in Windows - environment) exists, it will be used as global configuration file. - Alternatively, you can specify the global configuration file with the - ``--global-config`` option. - - Also, if ``setup.cfg``, ``tox.ini``, ``.pep8`` and ``.flake8`` files exist - in the directory where the target file exists, it will be used as the - configuration file. - - ``pep8``, ``pycodestyle``, and ``flake8`` can be used as a section. - - configuration file example:: - - [pycodestyle] - max_line_length = 120 - ignore = E501 - - pyproject.toml - -------------- - - autopep8 can also use ``pyproject.toml``. - section must use ``[tool.autopep8]``, and ``pyproject.toml`` takes precedence - over any other configuration files. - - configuration file example:: - - [tool.autopep8] - max_line_length = 120 - ignore = "E501,W6" # or ["E501", "W6"] - - - Testing - ======= - - Test cases are in ``test/test_autopep8.py``. They can be run directly via - ``python test/test_autopep8.py`` or via tox_. The latter is useful for - testing against multiple Python interpreters. (We currently test against - CPython versions 2.7, 3.4, 3.5, 3.6 and 3.7. We also test against PyPy.) - - .. _`tox`: https://pypi.org/project/tox/ - - Broad spectrum testing is available via ``test/acid.py``. This script runs - autopep8 against Python code and checks for correctness and completeness of the - code fixes. It can check that the bytecode remains identical. - ``test/acid_pypi.py`` makes use of ``acid.py`` to test against the latest - released packages on PyPI. - - - Troubleshooting - =============== - - ``pkg_resources.DistributionNotFound`` - -------------------------------------- - - If you are using an ancient version of ``setuptools``, you might encounter - ``pkg_resources.DistributionNotFound`` when trying to run ``autopep8``. Try - upgrading ``setuptools`` to workaround this ``setuptools`` problem:: - - $ pip install --upgrade setuptools - - Use ``sudo`` if you are installing to the system. - - - Links - ===== - - * PyPI_ - * GitHub_ - * `Travis CI`_ - * Coveralls_ - - .. _PyPI: https://pypi.org/project/autopep8/ - .. _GitHub: https://github.com/hhatto/autopep8 - .. _`Travis CI`: https://travis-ci.org/hhatto/autopep8 - .. _`Coveralls`: https://coveralls.io/r/hhatto/autopep8 - -Keywords: automation,pep8,format,pycodestyle -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Software Development :: Quality Assurance diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/SOURCES.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/SOURCES.txt deleted file mode 100644 index a43b6f43..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/SOURCES.txt +++ /dev/null @@ -1,25 +0,0 @@ -AUTHORS.rst -LICENSE -MANIFEST.in -README.rst -autopep8.py -setup.cfg -setup.py -autopep8.egg-info/PKG-INFO -autopep8.egg-info/SOURCES.txt -autopep8.egg-info/dependency_links.txt -autopep8.egg-info/entry_points.txt -autopep8.egg-info/not-zip-safe -autopep8.egg-info/requires.txt -autopep8.egg-info/top_level.txt -test/__init__.py -test/bad_encoding.py -test/bad_encoding2.py -test/e101_example.py -test/example.py -test/example_with_reduce.py -test/iso_8859_1.py -test/test_autopep8.py -test/test_suite.py -test/fake_configuration/.pep8 -test/fake_pycodestyle_configuration/tox.ini \ No newline at end of file diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/dependency_links.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/entry_points.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/entry_points.txt deleted file mode 100644 index e3b2c4f8..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -autopep8 = autopep8:main - diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/installed-files.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/installed-files.txt deleted file mode 100644 index ee37f885..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/installed-files.txt +++ /dev/null @@ -1,10 +0,0 @@ -../../../../bin/autopep8 -../__pycache__/autopep8.cpython-38.pyc -../autopep8.py -PKG-INFO -SOURCES.txt -dependency_links.txt -entry_points.txt -not-zip-safe -requires.txt -top_level.txt diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/not-zip-safe b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/not-zip-safe deleted file mode 100644 index 8b137891..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/requires.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/requires.txt deleted file mode 100644 index 0349aa7e..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/requires.txt +++ /dev/null @@ -1,2 +0,0 @@ -pycodestyle>=2.6.0 -toml diff --git a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/top_level.txt b/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/top_level.txt deleted file mode 100644 index d81c0c25..00000000 --- a/env/lib/python3.8/site-packages/autopep8-1.5.4.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -autopep8 diff --git a/env/lib/python3.8/site-packages/autopep8.py b/env/lib/python3.8/site-packages/autopep8.py deleted file mode 100644 index 47f83bd7..00000000 --- a/env/lib/python3.8/site-packages/autopep8.py +++ /dev/null @@ -1,4514 +0,0 @@ -#!/usr/bin/env python - -# Copyright (C) 2010-2011 Hideo Hattori -# Copyright (C) 2011-2013 Hideo Hattori, Steven Myint -# Copyright (C) 2013-2016 Hideo Hattori, Steven Myint, Bill Wendling -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""Automatically formats Python code to conform to the PEP 8 style guide. - -Fixes that only need be done once can be added by adding a function of the form -"fix_(source)" to this module. They should return the fixed source code. -These fixes are picked up by apply_global_fixes(). - -Fixes that depend on pycodestyle should be added as methods to FixPEP8. See the -class documentation for more information. - -""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -import argparse -import codecs -import collections -import copy -import difflib -import fnmatch -import inspect -import io -import itertools -import keyword -import locale -import os -import re -import signal -import sys -import textwrap -import token -import tokenize -import warnings -import ast -try: - from configparser import ConfigParser as SafeConfigParser - from configparser import Error -except ImportError: - from ConfigParser import SafeConfigParser - from ConfigParser import Error - -import toml -import pycodestyle -from pycodestyle import STARTSWITH_INDENT_STATEMENT_REGEX - - -try: - unicode -except NameError: - unicode = str - - -__version__ = '1.5.4' - - -CR = '\r' -LF = '\n' -CRLF = '\r\n' - - -PYTHON_SHEBANG_REGEX = re.compile(r'^#!.*\bpython[23]?\b\s*$') -LAMBDA_REGEX = re.compile(r'([\w.]+)\s=\slambda\s*([\(\)=\w,\s.]*):') -COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+([^][)(}{]+?)\s+(in|is)\s') -COMPARE_NEGATIVE_REGEX_THROUGH = re.compile(r'\b(not\s+in|is\s+not)\s') -BARE_EXCEPT_REGEX = re.compile(r'except\s*:') -STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\s.*\):') -DOCSTRING_START_REGEX = re.compile(r'^u?r?(?P["\']{3})') -ENABLE_REGEX = re.compile(r'# *(fmt|autopep8): *on') -DISABLE_REGEX = re.compile(r'# *(fmt|autopep8): *off') - -EXIT_CODE_OK = 0 -EXIT_CODE_ERROR = 1 -EXIT_CODE_EXISTS_DIFF = 2 - -# For generating line shortening candidates. -SHORTEN_OPERATOR_GROUPS = frozenset([ - frozenset([',']), - frozenset(['%']), - frozenset([',', '(', '[', '{']), - frozenset(['%', '(', '[', '{']), - frozenset([',', '(', '[', '{', '%', '+', '-', '*', '/', '//']), - frozenset(['%', '+', '-', '*', '/', '//']), -]) - - -DEFAULT_IGNORE = 'E226,E24,W50,W690' # TODO: use pycodestyle.DEFAULT_IGNORE -DEFAULT_INDENT_SIZE = 4 -# these fixes conflict with each other, if the `--ignore` setting causes both -# to be enabled, disable both of them -CONFLICTING_CODES = ('W503', 'W504') - -SELECTED_GLOBAL_FIXED_METHOD_CODES = ['W602', ] - -# W602 is handled separately due to the need to avoid "with_traceback". -CODE_TO_2TO3 = { - 'E231': ['ws_comma'], - 'E721': ['idioms'], - 'W601': ['has_key'], - 'W603': ['ne'], - 'W604': ['repr'], - 'W690': ['apply', - 'except', - 'exitfunc', - 'numliterals', - 'operator', - 'paren', - 'reduce', - 'renames', - 'standarderror', - 'sys_exc', - 'throw', - 'tuple_params', - 'xreadlines']} - - -if sys.platform == 'win32': # pragma: no cover - DEFAULT_CONFIG = os.path.expanduser(r'~\.pycodestyle') -else: - DEFAULT_CONFIG = os.path.join(os.getenv('XDG_CONFIG_HOME') or - os.path.expanduser('~/.config'), - 'pycodestyle') -# fallback, use .pep8 -if not os.path.exists(DEFAULT_CONFIG): # pragma: no cover - if sys.platform == 'win32': - DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8') - else: - DEFAULT_CONFIG = os.path.join(os.path.expanduser('~/.config'), 'pep8') -PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8', '.flake8') - - -MAX_PYTHON_FILE_DETECTION_BYTES = 1024 - - -def open_with_encoding(filename, mode='r', encoding=None, limit_byte_check=-1): - """Return opened file with a specific encoding.""" - if not encoding: - encoding = detect_encoding(filename, limit_byte_check=limit_byte_check) - - return io.open(filename, mode=mode, encoding=encoding, - newline='') # Preserve line endings - - -def detect_encoding(filename, limit_byte_check=-1): - """Return file encoding.""" - try: - with open(filename, 'rb') as input_file: - from lib2to3.pgen2 import tokenize as lib2to3_tokenize - encoding = lib2to3_tokenize.detect_encoding(input_file.readline)[0] - - with open_with_encoding(filename, encoding=encoding) as test_file: - test_file.read(limit_byte_check) - - return encoding - except (LookupError, SyntaxError, UnicodeDecodeError): - return 'latin-1' - - -def readlines_from_file(filename): - """Return contents of file.""" - with open_with_encoding(filename) as input_file: - return input_file.readlines() - - -def extended_blank_lines(logical_line, - blank_lines, - blank_before, - indent_level, - previous_logical): - """Check for missing blank lines after class declaration.""" - if previous_logical.startswith('def '): - if blank_lines and pycodestyle.DOCSTRING_REGEX.match(logical_line): - yield (0, 'E303 too many blank lines ({})'.format(blank_lines)) - elif pycodestyle.DOCSTRING_REGEX.match(previous_logical): - # Missing blank line between class docstring and method declaration. - if ( - indent_level and - not blank_lines and - not blank_before and - logical_line.startswith(('def ')) and - '(self' in logical_line - ): - yield (0, 'E301 expected 1 blank line, found 0') - - -pycodestyle.register_check(extended_blank_lines) - - -def continued_indentation(logical_line, tokens, indent_level, hang_closing, - indent_char, noqa): - """Override pycodestyle's function to provide indentation information.""" - first_row = tokens[0][2][0] - nrows = 1 + tokens[-1][2][0] - first_row - if noqa or nrows == 1: - return - - # indent_next tells us whether the next block is indented. Assuming - # that it is indented by 4 spaces, then we should not allow 4-space - # indents on the final continuation line. In turn, some other - # indents are allowed to have an extra 4 spaces. - indent_next = logical_line.endswith(':') - - row = depth = 0 - valid_hangs = ( - (DEFAULT_INDENT_SIZE,) - if indent_char != '\t' else (DEFAULT_INDENT_SIZE, - 2 * DEFAULT_INDENT_SIZE) - ) - - # Remember how many brackets were opened on each line. - parens = [0] * nrows - - # Relative indents of physical lines. - rel_indent = [0] * nrows - - # For each depth, collect a list of opening rows. - open_rows = [[0]] - # For each depth, memorize the hanging indentation. - hangs = [None] - - # Visual indents. - indent_chances = {} - last_indent = tokens[0][2] - indent = [last_indent[1]] - - last_token_multiline = None - line = None - last_line = '' - last_line_begins_with_multiline = False - for token_type, text, start, end, line in tokens: - - newline = row < start[0] - first_row - if newline: - row = start[0] - first_row - newline = (not last_token_multiline and - token_type not in (tokenize.NL, tokenize.NEWLINE)) - last_line_begins_with_multiline = last_token_multiline - - if newline: - # This is the beginning of a continuation line. - last_indent = start - - # Record the initial indent. - rel_indent[row] = pycodestyle.expand_indent(line) - indent_level - - # Identify closing bracket. - close_bracket = (token_type == tokenize.OP and text in ']})') - - # Is the indent relative to an opening bracket line? - for open_row in reversed(open_rows[depth]): - hang = rel_indent[row] - rel_indent[open_row] - hanging_indent = hang in valid_hangs - if hanging_indent: - break - if hangs[depth]: - hanging_indent = (hang == hangs[depth]) - - visual_indent = (not close_bracket and hang > 0 and - indent_chances.get(start[1])) - - if close_bracket and indent[depth]: - # Closing bracket for visual indent. - if start[1] != indent[depth]: - yield (start, 'E124 {}'.format(indent[depth])) - elif close_bracket and not hang: - # closing bracket matches indentation of opening bracket's line - if hang_closing: - yield (start, 'E133 {}'.format(indent[depth])) - elif indent[depth] and start[1] < indent[depth]: - # Visual indent is broken. - yield (start, 'E128 {}'.format(indent[depth])) - elif (hanging_indent or - (indent_next and - rel_indent[row] == 2 * DEFAULT_INDENT_SIZE)): - # Hanging indent is verified. - if close_bracket and not hang_closing: - yield (start, 'E123 {}'.format(indent_level + - rel_indent[open_row])) - hangs[depth] = hang - elif visual_indent is True: - # Visual indent is verified. - indent[depth] = start[1] - elif visual_indent in (text, unicode): - # Ignore token lined up with matching one from a previous line. - pass - else: - one_indented = (indent_level + rel_indent[open_row] + - DEFAULT_INDENT_SIZE) - # Indent is broken. - if hang <= 0: - error = ('E122', one_indented) - elif indent[depth]: - error = ('E127', indent[depth]) - elif not close_bracket and hangs[depth]: - error = ('E131', one_indented) - elif hang > DEFAULT_INDENT_SIZE: - error = ('E126', one_indented) - else: - hangs[depth] = hang - error = ('E121', one_indented) - - yield (start, '{} {}'.format(*error)) - - # Look for visual indenting. - if ( - parens[row] and - token_type not in (tokenize.NL, tokenize.COMMENT) and - not indent[depth] - ): - indent[depth] = start[1] - indent_chances[start[1]] = True - # Deal with implicit string concatenation. - elif (token_type in (tokenize.STRING, tokenize.COMMENT) or - text in ('u', 'ur', 'b', 'br')): - indent_chances[start[1]] = unicode - # Special case for the "if" statement because len("if (") is equal to - # 4. - elif not indent_chances and not row and not depth and text == 'if': - indent_chances[end[1] + 1] = True - elif text == ':' and line[end[1]:].isspace(): - open_rows[depth].append(row) - - # Keep track of bracket depth. - if token_type == tokenize.OP: - if text in '([{': - depth += 1 - indent.append(0) - hangs.append(None) - if len(open_rows) == depth: - open_rows.append([]) - open_rows[depth].append(row) - parens[row] += 1 - elif text in ')]}' and depth > 0: - # Parent indents should not be more than this one. - prev_indent = indent.pop() or last_indent[1] - hangs.pop() - for d in range(depth): - if indent[d] > prev_indent: - indent[d] = 0 - for ind in list(indent_chances): - if ind >= prev_indent: - del indent_chances[ind] - del open_rows[depth + 1:] - depth -= 1 - if depth: - indent_chances[indent[depth]] = True - for idx in range(row, -1, -1): - if parens[idx]: - parens[idx] -= 1 - break - assert len(indent) == depth + 1 - if ( - start[1] not in indent_chances and - # This is for purposes of speeding up E121 (GitHub #90). - not last_line.rstrip().endswith(',') - ): - # Allow to line up tokens. - indent_chances[start[1]] = text - - last_token_multiline = (start[0] != end[0]) - if last_token_multiline: - rel_indent[end[0] - first_row] = rel_indent[row] - - last_line = line - - if ( - indent_next and - not last_line_begins_with_multiline and - pycodestyle.expand_indent(line) == indent_level + DEFAULT_INDENT_SIZE - ): - pos = (start[0], indent[0] + 4) - desired_indent = indent_level + 2 * DEFAULT_INDENT_SIZE - if visual_indent: - yield (pos, 'E129 {}'.format(desired_indent)) - else: - yield (pos, 'E125 {}'.format(desired_indent)) - - -del pycodestyle._checks['logical_line'][pycodestyle.continued_indentation] -pycodestyle.register_check(continued_indentation) - - -class FixPEP8(object): - - """Fix invalid code. - - Fixer methods are prefixed "fix_". The _fix_source() method looks for these - automatically. - - The fixer method can take either one or two arguments (in addition to - self). The first argument is "result", which is the error information from - pycodestyle. The second argument, "logical", is required only for - logical-line fixes. - - The fixer method can return the list of modified lines or None. An empty - list would mean that no changes were made. None would mean that only the - line reported in the pycodestyle error was modified. Note that the modified - line numbers that are returned are indexed at 1. This typically would - correspond with the line number reported in the pycodestyle error - information. - - [fixed method list] - - e111,e114,e115,e116 - - e121,e122,e123,e124,e125,e126,e127,e128,e129 - - e201,e202,e203 - - e211 - - e221,e222,e223,e224,e225 - - e231 - - e251,e252 - - e261,e262 - - e271,e272,e273,e274 - - e301,e302,e303,e304,e305,e306 - - e401,e402 - - e502 - - e701,e702,e703,e704 - - e711,e712,e713,e714 - - e722 - - e731 - - w291 - - w503,504 - - """ - - def __init__(self, filename, - options, - contents=None, - long_line_ignore_cache=None): - self.filename = filename - if contents is None: - self.source = readlines_from_file(filename) - else: - sio = io.StringIO(contents) - self.source = sio.readlines() - self.options = options - self.indent_word = _get_indentword(''.join(self.source)) - - # collect imports line - self.imports = {} - for i, line in enumerate(self.source): - if (line.find("import ") == 0 or line.find("from ") == 0) and \ - line not in self.imports: - # collect only import statements that first appeared - self.imports[line] = i - - self.long_line_ignore_cache = ( - set() if long_line_ignore_cache is None - else long_line_ignore_cache) - - # Many fixers are the same even though pycodestyle categorizes them - # differently. - self.fix_e115 = self.fix_e112 - self.fix_e121 = self._fix_reindent - self.fix_e122 = self._fix_reindent - self.fix_e123 = self._fix_reindent - self.fix_e124 = self._fix_reindent - self.fix_e126 = self._fix_reindent - self.fix_e127 = self._fix_reindent - self.fix_e128 = self._fix_reindent - self.fix_e129 = self._fix_reindent - self.fix_e133 = self.fix_e131 - self.fix_e202 = self.fix_e201 - self.fix_e203 = self.fix_e201 - self.fix_e211 = self.fix_e201 - self.fix_e221 = self.fix_e271 - self.fix_e222 = self.fix_e271 - self.fix_e223 = self.fix_e271 - self.fix_e226 = self.fix_e225 - self.fix_e227 = self.fix_e225 - self.fix_e228 = self.fix_e225 - self.fix_e241 = self.fix_e271 - self.fix_e242 = self.fix_e224 - self.fix_e252 = self.fix_e225 - self.fix_e261 = self.fix_e262 - self.fix_e272 = self.fix_e271 - self.fix_e273 = self.fix_e271 - self.fix_e274 = self.fix_e271 - self.fix_e306 = self.fix_e301 - self.fix_e501 = ( - self.fix_long_line_logically if - options and (options.aggressive >= 2 or options.experimental) else - self.fix_long_line_physically) - self.fix_e703 = self.fix_e702 - self.fix_w293 = self.fix_w291 - - def _fix_source(self, results): - try: - (logical_start, logical_end) = _find_logical(self.source) - logical_support = True - except (SyntaxError, tokenize.TokenError): # pragma: no cover - logical_support = False - - completed_lines = set() - for result in sorted(results, key=_priority_key): - if result['line'] in completed_lines: - continue - - fixed_methodname = 'fix_' + result['id'].lower() - if hasattr(self, fixed_methodname): - fix = getattr(self, fixed_methodname) - - line_index = result['line'] - 1 - original_line = self.source[line_index] - - is_logical_fix = len(_get_parameters(fix)) > 2 - if is_logical_fix: - logical = None - if logical_support: - logical = _get_logical(self.source, - result, - logical_start, - logical_end) - if logical and set(range( - logical[0][0] + 1, - logical[1][0] + 1)).intersection( - completed_lines): - continue - - modified_lines = fix(result, logical) - else: - modified_lines = fix(result) - - if modified_lines is None: - # Force logical fixes to report what they modified. - assert not is_logical_fix - - if self.source[line_index] == original_line: - modified_lines = [] - - if modified_lines: - completed_lines.update(modified_lines) - elif modified_lines == []: # Empty list means no fix - if self.options.verbose >= 2: - print( - '---> Not fixing {error} on line {line}'.format( - error=result['id'], line=result['line']), - file=sys.stderr) - else: # We assume one-line fix when None. - completed_lines.add(result['line']) - else: - if self.options.verbose >= 3: - print( - "---> '{}' is not defined.".format(fixed_methodname), - file=sys.stderr) - - info = result['info'].strip() - print('---> {}:{}:{}:{}'.format(self.filename, - result['line'], - result['column'], - info), - file=sys.stderr) - - def fix(self): - """Return a version of the source code with PEP 8 violations fixed.""" - pep8_options = { - 'ignore': self.options.ignore, - 'select': self.options.select, - 'max_line_length': self.options.max_line_length, - 'hang_closing': self.options.hang_closing, - } - results = _execute_pep8(pep8_options, self.source) - - if self.options.verbose: - progress = {} - for r in results: - if r['id'] not in progress: - progress[r['id']] = set() - progress[r['id']].add(r['line']) - print('---> {n} issue(s) to fix {progress}'.format( - n=len(results), progress=progress), file=sys.stderr) - - if self.options.line_range: - start, end = self.options.line_range - results = [r for r in results - if start <= r['line'] <= end] - - self._fix_source(filter_results(source=''.join(self.source), - results=results, - aggressive=self.options.aggressive)) - - if self.options.line_range: - # If number of lines has changed then change line_range. - count = sum(sline.count('\n') - for sline in self.source[start - 1:end]) - self.options.line_range[1] = start + count - 1 - - return ''.join(self.source) - - def _fix_reindent(self, result): - """Fix a badly indented line. - - This is done by adding or removing from its initial indent only. - - """ - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 - target = self.source[line_index] - - self.source[line_index] = ' ' * num_indent_spaces + target.lstrip() - - def fix_e112(self, result): - """Fix under-indented comments.""" - line_index = result['line'] - 1 - target = self.source[line_index] - - if not target.lstrip().startswith('#'): - # Don't screw with invalid syntax. - return [] - - self.source[line_index] = self.indent_word + target - - def fix_e113(self, result): - """Fix unexpected indentation.""" - line_index = result['line'] - 1 - target = self.source[line_index] - indent = _get_indentation(target) - stripped = target.lstrip() - self.source[line_index] = indent[1:] + stripped - - def fix_e116(self, result): - """Fix over-indented comments.""" - line_index = result['line'] - 1 - target = self.source[line_index] - - indent = _get_indentation(target) - stripped = target.lstrip() - - if not stripped.startswith('#'): - # Don't screw with invalid syntax. - return [] - - self.source[line_index] = indent[1:] + stripped - - def fix_e117(self, result): - """Fix over-indented.""" - line_index = result['line'] - 1 - target = self.source[line_index] - - indent = _get_indentation(target) - if indent == '\t': - return [] - - stripped = target.lstrip() - - self.source[line_index] = indent[1:] + stripped - - def fix_e125(self, result): - """Fix indentation undistinguish from the next logical line.""" - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 - target = self.source[line_index] - - spaces_to_add = num_indent_spaces - len(_get_indentation(target)) - indent = len(_get_indentation(target)) - modified_lines = [] - - while len(_get_indentation(self.source[line_index])) >= indent: - self.source[line_index] = (' ' * spaces_to_add + - self.source[line_index]) - modified_lines.append(1 + line_index) # Line indexed at 1. - line_index -= 1 - - return modified_lines - - def fix_e131(self, result): - """Fix indentation undistinguish from the next logical line.""" - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 - target = self.source[line_index] - - spaces_to_add = num_indent_spaces - len(_get_indentation(target)) - - if spaces_to_add >= 0: - self.source[line_index] = (' ' * spaces_to_add + - self.source[line_index]) - else: - offset = abs(spaces_to_add) - self.source[line_index] = self.source[line_index][offset:] - - def fix_e201(self, result): - """Remove extraneous whitespace.""" - line_index = result['line'] - 1 - target = self.source[line_index] - offset = result['column'] - 1 - - fixed = fix_whitespace(target, - offset=offset, - replacement='') - - self.source[line_index] = fixed - - def fix_e224(self, result): - """Remove extraneous whitespace around operator.""" - target = self.source[result['line'] - 1] - offset = result['column'] - 1 - fixed = target[:offset] + target[offset:].replace('\t', ' ') - self.source[result['line'] - 1] = fixed - - def fix_e225(self, result): - """Fix missing whitespace around operator.""" - target = self.source[result['line'] - 1] - offset = result['column'] - 1 - fixed = target[:offset] + ' ' + target[offset:] - - # Only proceed if non-whitespace characters match. - # And make sure we don't break the indentation. - if ( - fixed.replace(' ', '') == target.replace(' ', '') and - _get_indentation(fixed) == _get_indentation(target) - ): - self.source[result['line'] - 1] = fixed - error_code = result.get('id', 0) - try: - ts = generate_tokens(fixed) - except (SyntaxError, tokenize.TokenError): - return - if not check_syntax(fixed.lstrip()): - return - errors = list( - pycodestyle.missing_whitespace_around_operator(fixed, ts)) - for e in reversed(errors): - if error_code != e[1].split()[0]: - continue - offset = e[0][1] - fixed = fixed[:offset] + ' ' + fixed[offset:] - self.source[result['line'] - 1] = fixed - else: - return [] - - def fix_e231(self, result): - """Add missing whitespace.""" - line_index = result['line'] - 1 - target = self.source[line_index] - offset = result['column'] - fixed = target[:offset].rstrip() + ' ' + target[offset:].lstrip() - self.source[line_index] = fixed - - def fix_e251(self, result): - """Remove whitespace around parameter '=' sign.""" - line_index = result['line'] - 1 - target = self.source[line_index] - - # This is necessary since pycodestyle sometimes reports columns that - # goes past the end of the physical line. This happens in cases like, - # foo(bar\n=None) - c = min(result['column'] - 1, - len(target) - 1) - - if target[c].strip(): - fixed = target - else: - fixed = target[:c].rstrip() + target[c:].lstrip() - - # There could be an escaped newline - # - # def foo(a=\ - # 1) - if fixed.endswith(('=\\\n', '=\\\r\n', '=\\\r')): - self.source[line_index] = fixed.rstrip('\n\r \t\\') - self.source[line_index + 1] = self.source[line_index + 1].lstrip() - return [line_index + 1, line_index + 2] # Line indexed at 1 - - self.source[result['line'] - 1] = fixed - - def fix_e262(self, result): - """Fix spacing after comment hash.""" - target = self.source[result['line'] - 1] - offset = result['column'] - - code = target[:offset].rstrip(' \t#') - comment = target[offset:].lstrip(' \t#') - - fixed = code + (' # ' + comment if comment.strip() else '\n') - - self.source[result['line'] - 1] = fixed - - def fix_e271(self, result): - """Fix extraneous whitespace around keywords.""" - line_index = result['line'] - 1 - target = self.source[line_index] - offset = result['column'] - 1 - - fixed = fix_whitespace(target, - offset=offset, - replacement=' ') - - if fixed == target: - return [] - else: - self.source[line_index] = fixed - - def fix_e301(self, result): - """Add missing blank line.""" - cr = '\n' - self.source[result['line'] - 1] = cr + self.source[result['line'] - 1] - - def fix_e302(self, result): - """Add missing 2 blank lines.""" - add_linenum = 2 - int(result['info'].split()[-1]) - offset = 1 - if self.source[result['line'] - 2].strip() == "\\": - offset = 2 - cr = '\n' * add_linenum - self.source[result['line'] - offset] = ( - cr + self.source[result['line'] - offset] - ) - - def fix_e303(self, result): - """Remove extra blank lines.""" - delete_linenum = int(result['info'].split('(')[1].split(')')[0]) - 2 - delete_linenum = max(1, delete_linenum) - - # We need to count because pycodestyle reports an offset line number if - # there are comments. - cnt = 0 - line = result['line'] - 2 - modified_lines = [] - while cnt < delete_linenum and line >= 0: - if not self.source[line].strip(): - self.source[line] = '' - modified_lines.append(1 + line) # Line indexed at 1 - cnt += 1 - line -= 1 - - return modified_lines - - def fix_e304(self, result): - """Remove blank line following function decorator.""" - line = result['line'] - 2 - if not self.source[line].strip(): - self.source[line] = '' - - def fix_e305(self, result): - """Add missing 2 blank lines after end of function or class.""" - add_delete_linenum = 2 - int(result['info'].split()[-1]) - cnt = 0 - offset = result['line'] - 2 - modified_lines = [] - if add_delete_linenum < 0: - # delete cr - add_delete_linenum = abs(add_delete_linenum) - while cnt < add_delete_linenum and offset >= 0: - if not self.source[offset].strip(): - self.source[offset] = '' - modified_lines.append(1 + offset) # Line indexed at 1 - cnt += 1 - offset -= 1 - else: - # add cr - cr = '\n' - # check comment line - while True: - if offset < 0: - break - line = self.source[offset].lstrip() - if not line: - break - if line[0] != '#': - break - offset -= 1 - offset += 1 - self.source[offset] = cr + self.source[offset] - modified_lines.append(1 + offset) # Line indexed at 1. - return modified_lines - - def fix_e401(self, result): - """Put imports on separate lines.""" - line_index = result['line'] - 1 - target = self.source[line_index] - offset = result['column'] - 1 - - if not target.lstrip().startswith('import'): - return [] - - indentation = re.split(pattern=r'\bimport\b', - string=target, maxsplit=1)[0] - fixed = (target[:offset].rstrip('\t ,') + '\n' + - indentation + 'import ' + target[offset:].lstrip('\t ,')) - self.source[line_index] = fixed - - def fix_e402(self, result): - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - for i in range(1, 100): - line = "".join(self.source[line_index:line_index+i]) - try: - generate_tokens("".join(line)) - except (SyntaxError, tokenize.TokenError): - continue - break - if not (target in self.imports and self.imports[target] != line_index): - mod_offset = get_module_imports_on_top_of_file(self.source, - line_index) - self.source[mod_offset] = line + self.source[mod_offset] - for offset in range(i): - self.source[line_index+offset] = '' - - def fix_long_line_logically(self, result, logical): - """Try to make lines fit within --max-line-length characters.""" - if ( - not logical or - len(logical[2]) == 1 or - self.source[result['line'] - 1].lstrip().startswith('#') - ): - return self.fix_long_line_physically(result) - - start_line_index = logical[0][0] - end_line_index = logical[1][0] - logical_lines = logical[2] - - previous_line = get_item(self.source, start_line_index - 1, default='') - next_line = get_item(self.source, end_line_index + 1, default='') - - single_line = join_logical_line(''.join(logical_lines)) - - try: - fixed = self.fix_long_line( - target=single_line, - previous_line=previous_line, - next_line=next_line, - original=''.join(logical_lines)) - except (SyntaxError, tokenize.TokenError): - return self.fix_long_line_physically(result) - - if fixed: - for line_index in range(start_line_index, end_line_index + 1): - self.source[line_index] = '' - self.source[start_line_index] = fixed - return range(start_line_index + 1, end_line_index + 1) - - return [] - - def fix_long_line_physically(self, result): - """Try to make lines fit within --max-line-length characters.""" - line_index = result['line'] - 1 - target = self.source[line_index] - - previous_line = get_item(self.source, line_index - 1, default='') - next_line = get_item(self.source, line_index + 1, default='') - - try: - fixed = self.fix_long_line( - target=target, - previous_line=previous_line, - next_line=next_line, - original=target) - except (SyntaxError, tokenize.TokenError): - return [] - - if fixed: - self.source[line_index] = fixed - return [line_index + 1] - - return [] - - def fix_long_line(self, target, previous_line, - next_line, original): - cache_entry = (target, previous_line, next_line) - if cache_entry in self.long_line_ignore_cache: - return [] - - if target.lstrip().startswith('#'): - if self.options.aggressive: - # Wrap commented lines. - return shorten_comment( - line=target, - max_line_length=self.options.max_line_length, - last_comment=not next_line.lstrip().startswith('#')) - return [] - - fixed = get_fixed_long_line( - target=target, - previous_line=previous_line, - original=original, - indent_word=self.indent_word, - max_line_length=self.options.max_line_length, - aggressive=self.options.aggressive, - experimental=self.options.experimental, - verbose=self.options.verbose) - - if fixed and not code_almost_equal(original, fixed): - return fixed - - self.long_line_ignore_cache.add(cache_entry) - return None - - def fix_e502(self, result): - """Remove extraneous escape of newline.""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) - self.source[line_index] = target.rstrip('\n\r \t\\') + '\n' - - def fix_e701(self, result): - """Put colon-separated compound statement on separate lines.""" - line_index = result['line'] - 1 - target = self.source[line_index] - c = result['column'] - - fixed_source = (target[:c] + '\n' + - _get_indentation(target) + self.indent_word + - target[c:].lstrip('\n\r \t\\')) - self.source[result['line'] - 1] = fixed_source - return [result['line'], result['line'] + 1] - - def fix_e702(self, result, logical): - """Put semicolon-separated compound statement on separate lines.""" - if not logical: - return [] # pragma: no cover - logical_lines = logical[2] - - # Avoid applying this when indented. - # https://docs.python.org/reference/compound_stmts.html - for line in logical_lines: - if (result['id'] == 'E702' and ':' in line - and STARTSWITH_INDENT_STATEMENT_REGEX.match(line)): - if self.options.verbose: - print( - '---> avoid fixing {error} with ' - 'other compound statements'.format(error=result['id']), - file=sys.stderr - ) - return [] - - line_index = result['line'] - 1 - target = self.source[line_index] - - if target.rstrip().endswith('\\'): - # Normalize '1; \\\n2' into '1; 2'. - self.source[line_index] = target.rstrip('\n \r\t\\') - self.source[line_index + 1] = self.source[line_index + 1].lstrip() - return [line_index + 1, line_index + 2] - - if target.rstrip().endswith(';'): - self.source[line_index] = target.rstrip('\n \r\t;') + '\n' - return [line_index + 1] - - offset = result['column'] - 1 - first = target[:offset].rstrip(';').rstrip() - second = (_get_indentation(logical_lines[0]) + - target[offset:].lstrip(';').lstrip()) - - # Find inline comment. - inline_comment = None - if target[offset:].lstrip(';').lstrip()[:2] == '# ': - inline_comment = target[offset:].lstrip(';') - - if inline_comment: - self.source[line_index] = first + inline_comment - else: - self.source[line_index] = first + '\n' + second - return [line_index + 1] - - def fix_e704(self, result): - """Fix multiple statements on one line def""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) - match = STARTSWITH_DEF_REGEX.match(target) - if match: - self.source[line_index] = '{}\n{}{}'.format( - match.group(0), - _get_indentation(target) + self.indent_word, - target[match.end(0):].lstrip()) - - def fix_e711(self, result): - """Fix comparison with None.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - - right_offset = offset + 2 - if right_offset >= len(target): - return [] - - left = target[:offset].rstrip() - center = target[offset:right_offset] - right = target[right_offset:].lstrip() - - if center.strip() == '==': - new_center = 'is' - elif center.strip() == '!=': - new_center = 'is not' - else: - return [] - - self.source[line_index] = ' '.join([left, new_center, right]) - - def fix_e712(self, result): - """Fix (trivial case of) comparison with boolean.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - - # Handle very easy "not" special cases. - if re.match(r'^\s*if [\w."\'\[\]]+ == False:$', target): - self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) == False:', - r'if not \1:', target, count=1) - elif re.match(r'^\s*if [\w."\'\[\]]+ != True:$', target): - self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) != True:', - r'if not \1:', target, count=1) - else: - right_offset = offset + 2 - if right_offset >= len(target): - return [] - - left = target[:offset].rstrip() - center = target[offset:right_offset] - right = target[right_offset:].lstrip() - - # Handle simple cases only. - new_right = None - if center.strip() == '==': - if re.match(r'\bTrue\b', right): - new_right = re.sub(r'\bTrue\b *', '', right, count=1) - elif center.strip() == '!=': - if re.match(r'\bFalse\b', right): - new_right = re.sub(r'\bFalse\b *', '', right, count=1) - - if new_right is None: - return [] - - if new_right[0].isalnum(): - new_right = ' ' + new_right - - self.source[line_index] = left + new_right - - def fix_e713(self, result): - """Fix (trivial case of) non-membership check.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - - # to convert once 'not in' -> 'in' - before_target = target[:offset] - target = target[offset:] - match_notin = COMPARE_NEGATIVE_REGEX_THROUGH.search(target) - notin_pos_start, notin_pos_end = 0, 0 - if match_notin: - notin_pos_start = match_notin.start(1) - notin_pos_end = match_notin.end() - target = '{}{} {}'.format( - target[:notin_pos_start], 'in', target[notin_pos_end:]) - - # fix 'not in' - match = COMPARE_NEGATIVE_REGEX.search(target) - if match: - if match.group(3) == 'in': - pos_start = match.start(1) - new_target = '{5}{0}{1} {2} {3} {4}'.format( - target[:pos_start], match.group(2), match.group(1), - match.group(3), target[match.end():], before_target) - if match_notin: - # revert 'in' -> 'not in' - pos_start = notin_pos_start + offset - pos_end = notin_pos_end + offset - 4 # len('not ') - new_target = '{}{} {}'.format( - new_target[:pos_start], 'not in', new_target[pos_end:]) - self.source[line_index] = new_target - - def fix_e714(self, result): - """Fix object identity should be 'is not' case.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - - # to convert once 'is not' -> 'is' - before_target = target[:offset] - target = target[offset:] - match_isnot = COMPARE_NEGATIVE_REGEX_THROUGH.search(target) - isnot_pos_start, isnot_pos_end = 0, 0 - if match_isnot: - isnot_pos_start = match_isnot.start(1) - isnot_pos_end = match_isnot.end() - target = '{}{} {}'.format( - target[:isnot_pos_start], 'in', target[isnot_pos_end:]) - - match = COMPARE_NEGATIVE_REGEX.search(target) - if match: - if match.group(3).startswith('is'): - pos_start = match.start(1) - new_target = '{5}{0}{1} {2} {3} {4}'.format( - target[:pos_start], match.group(2), match.group(3), - match.group(1), target[match.end():], before_target) - if match_isnot: - # revert 'is' -> 'is not' - pos_start = isnot_pos_start + offset - pos_end = isnot_pos_end + offset - 4 # len('not ') - new_target = '{}{} {}'.format( - new_target[:pos_start], 'is not', new_target[pos_end:]) - self.source[line_index] = new_target - - def fix_e722(self, result): - """fix bare except""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) - match = BARE_EXCEPT_REGEX.search(target) - if match: - self.source[line_index] = '{}{}{}'.format( - target[:result['column'] - 1], "except BaseException:", - target[match.end():]) - - def fix_e731(self, result): - """Fix do not assign a lambda expression check.""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) - match = LAMBDA_REGEX.search(target) - if match: - end = match.end() - self.source[line_index] = '{}def {}({}): return {}'.format( - target[:match.start(0)], match.group(1), match.group(2), - target[end:].lstrip()) - - def fix_w291(self, result): - """Remove trailing whitespace.""" - fixed_line = self.source[result['line'] - 1].rstrip() - self.source[result['line'] - 1] = fixed_line + '\n' - - def fix_w391(self, _): - """Remove trailing blank lines.""" - blank_count = 0 - for line in reversed(self.source): - line = line.rstrip() - if line: - break - else: - blank_count += 1 - - original_length = len(self.source) - self.source = self.source[:original_length - blank_count] - return range(1, 1 + original_length) - - def fix_w503(self, result): - (line_index, _, target) = get_index_offset_contents(result, - self.source) - one_string_token = target.split()[0] - try: - ts = generate_tokens(one_string_token) - except (SyntaxError, tokenize.TokenError): - return - if not _is_binary_operator(ts[0][0], one_string_token): - return - # find comment - comment_index = 0 - found_not_comment_only_line = False - comment_only_linenum = 0 - for i in range(5): - # NOTE: try to parse code in 5 times - if (line_index - i) < 0: - break - from_index = line_index - i - 1 - if from_index < 0 or len(self.source) <= from_index: - break - to_index = line_index + 1 - strip_line = self.source[from_index].lstrip() - if ( - not found_not_comment_only_line and - strip_line and strip_line[0] == '#' - ): - comment_only_linenum += 1 - continue - found_not_comment_only_line = True - try: - ts = generate_tokens("".join(self.source[from_index:to_index])) - except (SyntaxError, tokenize.TokenError): - continue - newline_count = 0 - newline_index = [] - for index, t in enumerate(ts): - if t[0] in (tokenize.NEWLINE, tokenize.NL): - newline_index.append(index) - newline_count += 1 - if newline_count > 2: - tts = ts[newline_index[-3]:] - else: - tts = ts - old = [] - for t in tts: - if t[0] in (tokenize.NEWLINE, tokenize.NL): - newline_count -= 1 - if newline_count <= 1: - break - if tokenize.COMMENT == t[0] and old and old[0] != tokenize.NL: - comment_index = old[3][1] - break - old = t - break - i = target.index(one_string_token) - fix_target_line = line_index - 1 - comment_only_linenum - self.source[line_index] = '{}{}'.format( - target[:i], target[i + len(one_string_token):].lstrip()) - nl = find_newline(self.source[fix_target_line:line_index]) - before_line = self.source[fix_target_line] - bl = before_line.index(nl) - if comment_index: - self.source[fix_target_line] = '{} {} {}'.format( - before_line[:comment_index], one_string_token, - before_line[comment_index + 1:]) - else: - if before_line[:bl].endswith("#"): - # special case - # see: https://github.com/hhatto/autopep8/issues/503 - self.source[fix_target_line] = '{}{} {}'.format( - before_line[:bl-2], one_string_token, before_line[bl-2:]) - else: - self.source[fix_target_line] = '{} {}{}'.format( - before_line[:bl], one_string_token, before_line[bl:]) - - def fix_w504(self, result): - (line_index, _, target) = get_index_offset_contents(result, - self.source) - # NOTE: is not collect pointed out in pycodestyle==2.4.0 - comment_index = 0 - operator_position = None # (start_position, end_position) - for i in range(1, 6): - to_index = line_index + i - try: - ts = generate_tokens("".join(self.source[line_index:to_index])) - except (SyntaxError, tokenize.TokenError): - continue - newline_count = 0 - newline_index = [] - for index, t in enumerate(ts): - if _is_binary_operator(t[0], t[1]): - if t[2][0] == 1 and t[3][0] == 1: - operator_position = (t[2][1], t[3][1]) - elif t[0] == tokenize.NAME and t[1] in ("and", "or"): - if t[2][0] == 1 and t[3][0] == 1: - operator_position = (t[2][1], t[3][1]) - elif t[0] in (tokenize.NEWLINE, tokenize.NL): - newline_index.append(index) - newline_count += 1 - if newline_count > 2: - tts = ts[:newline_index[-3]] - else: - tts = ts - old = [] - for t in tts: - if tokenize.COMMENT == t[0] and old: - comment_row, comment_index = old[3] - break - old = t - break - if not operator_position: - return - target_operator = target[operator_position[0]:operator_position[1]] - - if comment_index and comment_row == 1: - self.source[line_index] = '{}{}'.format( - target[:operator_position[0]].rstrip(), - target[comment_index:]) - else: - self.source[line_index] = '{}{}{}'.format( - target[:operator_position[0]].rstrip(), - target[operator_position[1]:].lstrip(), - target[operator_position[1]:]) - - next_line = self.source[line_index + 1] - next_line_indent = 0 - m = re.match(r'\s*', next_line) - if m: - next_line_indent = m.span()[1] - self.source[line_index + 1] = '{}{} {}'.format( - next_line[:next_line_indent], target_operator, - next_line[next_line_indent:]) - - def fix_w605(self, result): - (line_index, _, target) = get_index_offset_contents(result, - self.source) - try: - tokens = list(generate_tokens(target)) - except (SyntaxError, tokenize.TokenError): - return - for (pos, _msg) in get_w605_position(tokens): - if target[pos - 1] == "r": - # ignore special case - if self.options.verbose: - print("invalid line: line_number={}, line: {}".format( - line_index + 1, target)) - return - self.source[line_index] = '{}r{}'.format( - target[:pos], target[pos:]) - - -def get_w605_position(tokens): - """workaround get pointing out position by W605.""" - # TODO: When this PR(*) change is released, use pos of pycodestyle - # *: https://github.com/PyCQA/pycodestyle/pull/747 - valid = [ - '\n', '\\', '\'', '"', 'a', 'b', 'f', 'n', 'r', 't', 'v', - '0', '1', '2', '3', '4', '5', '6', '7', 'x', - - # Escape sequences only recognized in string literals - 'N', 'u', 'U', - ] - - for token_type, text, start_pos, _end_pos, _line in tokens: - if token_type == tokenize.STRING: - quote = text[-3:] if text[-3:] in ('"""', "'''") else text[-1] - # Extract string modifiers (e.g. u or r) - quote_pos = text.index(quote) - prefix = text[:quote_pos].lower() - start = quote_pos + len(quote) - string = text[start:-len(quote)] - - if 'r' not in prefix: - pos = string.find('\\') - while pos >= 0: - pos += 1 - if string[pos] not in valid: - yield ( - # No need to search line, token stores position - start_pos[1], - "W605 invalid escape sequence '\\%s'" % - string[pos], - ) - pos = string.find('\\', pos + 1) - - -def get_module_imports_on_top_of_file(source, import_line_index): - """return import or from keyword position - - example: - > 0: import sys - 1: import os - 2: - 3: def function(): - """ - def is_string_literal(line): - if line[0] in 'uUbB': - line = line[1:] - if line and line[0] in 'rR': - line = line[1:] - return line and (line[0] == '"' or line[0] == "'") - - def is_future_import(line): - nodes = ast.parse(line) - for n in nodes.body: - if isinstance(n, ast.ImportFrom) and n.module == '__future__': - return True - return False - - def has_future_import(source): - offset = 0 - line = '' - for _, next_line in source: - for line_part in next_line.strip().splitlines(True): - line = line + line_part - try: - return is_future_import(line), offset - except SyntaxError: - continue - offset += 1 - return False, offset - - allowed_try_keywords = ('try', 'except', 'else', 'finally') - in_docstring = False - docstring_kind = '"""' - source_stream = iter(enumerate(source)) - for cnt, line in source_stream: - if not in_docstring: - m = DOCSTRING_START_REGEX.match(line.lstrip()) - if m is not None: - in_docstring = True - docstring_kind = m.group('kind') - remain = line[m.end(): m.endpos].rstrip() - if remain[-3:] == docstring_kind: # one line doc - in_docstring = False - continue - if in_docstring: - if line.rstrip()[-3:] == docstring_kind: - in_docstring = False - continue - - if not line.rstrip(): - continue - elif line.startswith('#'): - continue - - if line.startswith('import '): - if cnt == import_line_index: - continue - return cnt - elif line.startswith('from '): - if cnt == import_line_index: - continue - hit, offset = has_future_import( - itertools.chain([(cnt, line)], source_stream) - ) - if hit: - # move to the back - return cnt + offset + 1 - return cnt - elif pycodestyle.DUNDER_REGEX.match(line): - return cnt - elif any(line.startswith(kw) for kw in allowed_try_keywords): - continue - elif is_string_literal(line): - return cnt - else: - return cnt - return 0 - - -def get_index_offset_contents(result, source): - """Return (line_index, column_offset, line_contents).""" - line_index = result['line'] - 1 - return (line_index, - result['column'] - 1, - source[line_index]) - - -def get_fixed_long_line(target, previous_line, original, - indent_word=' ', max_line_length=79, - aggressive=False, experimental=False, verbose=False): - """Break up long line and return result. - - Do this by generating multiple reformatted candidates and then - ranking the candidates to heuristically select the best option. - - """ - indent = _get_indentation(target) - source = target[len(indent):] - assert source.lstrip() == source - assert not target.lstrip().startswith('#') - - # Check for partial multiline. - tokens = list(generate_tokens(source)) - - candidates = shorten_line( - tokens, source, indent, - indent_word, - max_line_length, - aggressive=aggressive, - experimental=experimental, - previous_line=previous_line) - - # Also sort alphabetically as a tie breaker (for determinism). - candidates = sorted( - sorted(set(candidates).union([target, original])), - key=lambda x: line_shortening_rank( - x, - indent_word, - max_line_length, - experimental=experimental)) - - if verbose >= 4: - print(('-' * 79 + '\n').join([''] + candidates + ['']), - file=wrap_output(sys.stderr, 'utf-8')) - - if candidates: - best_candidate = candidates[0] - - # Don't allow things to get longer. - if longest_line_length(best_candidate) > longest_line_length(original): - return None - - return best_candidate - - -def longest_line_length(code): - """Return length of longest line.""" - if len(code) == 0: - return 0 - return max(len(line) for line in code.splitlines()) - - -def join_logical_line(logical_line): - """Return single line based on logical line input.""" - indentation = _get_indentation(logical_line) - - return indentation + untokenize_without_newlines( - generate_tokens(logical_line.lstrip())) + '\n' - - -def untokenize_without_newlines(tokens): - """Return source code based on tokens.""" - text = '' - last_row = 0 - last_column = -1 - - for t in tokens: - token_string = t[1] - (start_row, start_column) = t[2] - (end_row, end_column) = t[3] - - if start_row > last_row: - last_column = 0 - if ( - (start_column > last_column or token_string == '\n') and - not text.endswith(' ') - ): - text += ' ' - - if token_string != '\n': - text += token_string - - last_row = end_row - last_column = end_column - - return text.rstrip() - - -def _find_logical(source_lines): - # Make a variable which is the index of all the starts of lines. - logical_start = [] - logical_end = [] - last_newline = True - parens = 0 - for t in generate_tokens(''.join(source_lines)): - if t[0] in [tokenize.COMMENT, tokenize.DEDENT, - tokenize.INDENT, tokenize.NL, - tokenize.ENDMARKER]: - continue - if not parens and t[0] in [tokenize.NEWLINE, tokenize.SEMI]: - last_newline = True - logical_end.append((t[3][0] - 1, t[2][1])) - continue - if last_newline and not parens: - logical_start.append((t[2][0] - 1, t[2][1])) - last_newline = False - if t[0] == tokenize.OP: - if t[1] in '([{': - parens += 1 - elif t[1] in '}])': - parens -= 1 - return (logical_start, logical_end) - - -def _get_logical(source_lines, result, logical_start, logical_end): - """Return the logical line corresponding to the result. - - Assumes input is already E702-clean. - - """ - row = result['line'] - 1 - col = result['column'] - 1 - ls = None - le = None - for i in range(0, len(logical_start), 1): - assert logical_end - x = logical_end[i] - if x[0] > row or (x[0] == row and x[1] > col): - le = x - ls = logical_start[i] - break - if ls is None: - return None - original = source_lines[ls[0]:le[0] + 1] - return ls, le, original - - -def get_item(items, index, default=None): - if 0 <= index < len(items): - return items[index] - - return default - - -def reindent(source, indent_size): - """Reindent all lines.""" - reindenter = Reindenter(source) - return reindenter.run(indent_size) - - -def code_almost_equal(a, b): - """Return True if code is similar. - - Ignore whitespace when comparing specific line. - - """ - split_a = split_and_strip_non_empty_lines(a) - split_b = split_and_strip_non_empty_lines(b) - - if len(split_a) != len(split_b): - return False - - for (index, _) in enumerate(split_a): - if ''.join(split_a[index].split()) != ''.join(split_b[index].split()): - return False - - return True - - -def split_and_strip_non_empty_lines(text): - """Return lines split by newline. - - Ignore empty lines. - - """ - return [line.strip() for line in text.splitlines() if line.strip()] - - -def fix_e265(source, aggressive=False): # pylint: disable=unused-argument - """Format block comments.""" - if '#' not in source: - # Optimization. - return source - - ignored_line_numbers = multiline_string_lines( - source, - include_docstrings=True) | set(commented_out_code_lines(source)) - - fixed_lines = [] - sio = io.StringIO(source) - for (line_number, line) in enumerate(sio.readlines(), start=1): - if ( - line.lstrip().startswith('#') and - line_number not in ignored_line_numbers and - not pycodestyle.noqa(line) - ): - indentation = _get_indentation(line) - line = line.lstrip() - - # Normalize beginning if not a shebang. - if len(line) > 1: - pos = next((index for index, c in enumerate(line) - if c != '#')) - if ( - # Leave multiple spaces like '# ' alone. - (line[:pos].count('#') > 1 or line[1].isalnum() or - not line[1].isspace()) and - line[1] not in ':!' and - # Leave stylistic outlined blocks alone. - not line.rstrip().endswith('#') - ): - line = '# ' + line.lstrip('# \t') - - fixed_lines.append(indentation + line) - else: - fixed_lines.append(line) - - return ''.join(fixed_lines) - - -def refactor(source, fixer_names, ignore=None, filename=''): - """Return refactored code using lib2to3. - - Skip if ignore string is produced in the refactored code. - - """ - from lib2to3 import pgen2 - try: - new_text = refactor_with_2to3(source, - fixer_names=fixer_names, - filename=filename) - except (pgen2.parse.ParseError, - SyntaxError, - UnicodeDecodeError, - UnicodeEncodeError): - return source - - if ignore: - if ignore in new_text and ignore not in source: - return source - - return new_text - - -def code_to_2to3(select, ignore, where='', verbose=False): - fixes = set() - for code, fix in CODE_TO_2TO3.items(): - if code_match(code, select=select, ignore=ignore): - if verbose: - print('---> Applying {} fix for {}'.format(where, - code.upper()), - file=sys.stderr) - fixes |= set(fix) - return fixes - - -def fix_2to3(source, - aggressive=True, select=None, ignore=None, filename='', - where='global', verbose=False): - """Fix various deprecated code (via lib2to3).""" - if not aggressive: - return source - - select = select or [] - ignore = ignore or [] - - return refactor(source, - code_to_2to3(select=select, - ignore=ignore, - where=where, - verbose=verbose), - filename=filename) - - -def fix_w602(source, aggressive=True): - """Fix deprecated form of raising exception.""" - if not aggressive: - return source - - return refactor(source, ['raise'], ignore='with_traceback') - - -def find_newline(source): - """Return type of newline used in source. - - Input is a list of lines. - - """ - assert not isinstance(source, unicode) - - counter = collections.defaultdict(int) - for line in source: - if line.endswith(CRLF): - counter[CRLF] += 1 - elif line.endswith(CR): - counter[CR] += 1 - elif line.endswith(LF): - counter[LF] += 1 - - return (sorted(counter, key=counter.get, reverse=True) or [LF])[0] - - -def _get_indentword(source): - """Return indentation type.""" - indent_word = ' ' # Default in case source has no indentation - try: - for t in generate_tokens(source): - if t[0] == token.INDENT: - indent_word = t[1] - break - except (SyntaxError, tokenize.TokenError): - pass - return indent_word - - -def _get_indentation(line): - """Return leading whitespace.""" - if line.strip(): - non_whitespace_index = len(line) - len(line.lstrip()) - return line[:non_whitespace_index] - - return '' - - -def get_diff_text(old, new, filename): - """Return text of unified diff between old and new.""" - newline = '\n' - diff = difflib.unified_diff( - old, new, - 'original/' + filename, - 'fixed/' + filename, - lineterm=newline) - - text = '' - for line in diff: - text += line - - # Work around missing newline (http://bugs.python.org/issue2142). - if text and not line.endswith(newline): - text += newline + r'\ No newline at end of file' + newline - - return text - - -def _priority_key(pep8_result): - """Key for sorting PEP8 results. - - Global fixes should be done first. This is important for things like - indentation. - - """ - priority = [ - # Fix multiline colon-based before semicolon based. - 'e701', - # Break multiline statements early. - 'e702', - # Things that make lines longer. - 'e225', 'e231', - # Remove extraneous whitespace before breaking lines. - 'e201', - # Shorten whitespace in comment before resorting to wrapping. - 'e262' - ] - middle_index = 10000 - lowest_priority = [ - # We need to shorten lines last since the logical fixer can get in a - # loop, which causes us to exit early. - 'e501', - ] - key = pep8_result['id'].lower() - try: - return priority.index(key) - except ValueError: - try: - return middle_index + lowest_priority.index(key) + 1 - except ValueError: - return middle_index - - -def shorten_line(tokens, source, indentation, indent_word, max_line_length, - aggressive=False, experimental=False, previous_line=''): - """Separate line at OPERATOR. - - Multiple candidates will be yielded. - - """ - for candidate in _shorten_line(tokens=tokens, - source=source, - indentation=indentation, - indent_word=indent_word, - aggressive=aggressive, - previous_line=previous_line): - yield candidate - - if aggressive: - for key_token_strings in SHORTEN_OPERATOR_GROUPS: - shortened = _shorten_line_at_tokens( - tokens=tokens, - source=source, - indentation=indentation, - indent_word=indent_word, - key_token_strings=key_token_strings, - aggressive=aggressive) - - if shortened is not None and shortened != source: - yield shortened - - if experimental: - for shortened in _shorten_line_at_tokens_new( - tokens=tokens, - source=source, - indentation=indentation, - max_line_length=max_line_length): - - yield shortened - - -def _shorten_line(tokens, source, indentation, indent_word, - aggressive=False, previous_line=''): - """Separate line at OPERATOR. - - The input is expected to be free of newlines except for inside multiline - strings and at the end. - - Multiple candidates will be yielded. - - """ - for (token_type, - token_string, - start_offset, - end_offset) in token_offsets(tokens): - - if ( - token_type == tokenize.COMMENT and - not is_probably_part_of_multiline(previous_line) and - not is_probably_part_of_multiline(source) and - not source[start_offset + 1:].strip().lower().startswith( - ('noqa', 'pragma:', 'pylint:')) - ): - # Move inline comments to previous line. - first = source[:start_offset] - second = source[start_offset:] - yield (indentation + second.strip() + '\n' + - indentation + first.strip() + '\n') - elif token_type == token.OP and token_string != '=': - # Don't break on '=' after keyword as this violates PEP 8. - - assert token_type != token.INDENT - - first = source[:end_offset] - - second_indent = indentation - if (first.rstrip().endswith('(') and - source[end_offset:].lstrip().startswith(')')): - pass - elif first.rstrip().endswith('('): - second_indent += indent_word - elif '(' in first: - second_indent += ' ' * (1 + first.find('(')) - else: - second_indent += indent_word - - second = (second_indent + source[end_offset:].lstrip()) - if ( - not second.strip() or - second.lstrip().startswith('#') - ): - continue - - # Do not begin a line with a comma - if second.lstrip().startswith(','): - continue - # Do end a line with a dot - if first.rstrip().endswith('.'): - continue - if token_string in '+-*/': - fixed = first + ' \\' + '\n' + second - else: - fixed = first + '\n' + second - - # Only fix if syntax is okay. - if check_syntax(normalize_multiline(fixed) - if aggressive else fixed): - yield indentation + fixed - - -def _is_binary_operator(token_type, text): - return ((token_type == tokenize.OP or text in ['and', 'or']) and - text not in '()[]{},:.;@=%~') - - -# A convenient way to handle tokens. -Token = collections.namedtuple('Token', ['token_type', 'token_string', - 'spos', 'epos', 'line']) - - -class ReformattedLines(object): - - """The reflowed lines of atoms. - - Each part of the line is represented as an "atom." They can be moved - around when need be to get the optimal formatting. - - """ - - ########################################################################### - # Private Classes - - class _Indent(object): - - """Represent an indentation in the atom stream.""" - - def __init__(self, indent_amt): - self._indent_amt = indent_amt - - def emit(self): - return ' ' * self._indent_amt - - @property - def size(self): - return self._indent_amt - - class _Space(object): - - """Represent a space in the atom stream.""" - - def emit(self): - return ' ' - - @property - def size(self): - return 1 - - class _LineBreak(object): - - """Represent a line break in the atom stream.""" - - def emit(self): - return '\n' - - @property - def size(self): - return 0 - - def __init__(self, max_line_length): - self._max_line_length = max_line_length - self._lines = [] - self._bracket_depth = 0 - self._prev_item = None - self._prev_prev_item = None - - def __repr__(self): - return self.emit() - - ########################################################################### - # Public Methods - - def add(self, obj, indent_amt, break_after_open_bracket): - if isinstance(obj, Atom): - self._add_item(obj, indent_amt) - return - - self._add_container(obj, indent_amt, break_after_open_bracket) - - def add_comment(self, item): - num_spaces = 2 - if len(self._lines) > 1: - if isinstance(self._lines[-1], self._Space): - num_spaces -= 1 - if len(self._lines) > 2: - if isinstance(self._lines[-2], self._Space): - num_spaces -= 1 - - while num_spaces > 0: - self._lines.append(self._Space()) - num_spaces -= 1 - self._lines.append(item) - - def add_indent(self, indent_amt): - self._lines.append(self._Indent(indent_amt)) - - def add_line_break(self, indent): - self._lines.append(self._LineBreak()) - self.add_indent(len(indent)) - - def add_line_break_at(self, index, indent_amt): - self._lines.insert(index, self._LineBreak()) - self._lines.insert(index + 1, self._Indent(indent_amt)) - - def add_space_if_needed(self, curr_text, equal=False): - if ( - not self._lines or isinstance( - self._lines[-1], (self._LineBreak, self._Indent, self._Space)) - ): - return - - prev_text = unicode(self._prev_item) - prev_prev_text = ( - unicode(self._prev_prev_item) if self._prev_prev_item else '') - - if ( - # The previous item was a keyword or identifier and the current - # item isn't an operator that doesn't require a space. - ((self._prev_item.is_keyword or self._prev_item.is_string or - self._prev_item.is_name or self._prev_item.is_number) and - (curr_text[0] not in '([{.,:}])' or - (curr_text[0] == '=' and equal))) or - - # Don't place spaces around a '.', unless it's in an 'import' - # statement. - ((prev_prev_text != 'from' and prev_text[-1] != '.' and - curr_text != 'import') and - - # Don't place a space before a colon. - curr_text[0] != ':' and - - # Don't split up ending brackets by spaces. - ((prev_text[-1] in '}])' and curr_text[0] not in '.,}])') or - - # Put a space after a colon or comma. - prev_text[-1] in ':,' or - - # Put space around '=' if asked to. - (equal and prev_text == '=') or - - # Put spaces around non-unary arithmetic operators. - ((self._prev_prev_item and - (prev_text not in '+-' and - (self._prev_prev_item.is_name or - self._prev_prev_item.is_number or - self._prev_prev_item.is_string)) and - prev_text in ('+', '-', '%', '*', '/', '//', '**', 'in'))))) - ): - self._lines.append(self._Space()) - - def previous_item(self): - """Return the previous non-whitespace item.""" - return self._prev_item - - def fits_on_current_line(self, item_extent): - return self.current_size() + item_extent <= self._max_line_length - - def current_size(self): - """The size of the current line minus the indentation.""" - size = 0 - for item in reversed(self._lines): - size += item.size - if isinstance(item, self._LineBreak): - break - - return size - - def line_empty(self): - return (self._lines and - isinstance(self._lines[-1], - (self._LineBreak, self._Indent))) - - def emit(self): - string = '' - for item in self._lines: - if isinstance(item, self._LineBreak): - string = string.rstrip() - string += item.emit() - - return string.rstrip() + '\n' - - ########################################################################### - # Private Methods - - def _add_item(self, item, indent_amt): - """Add an item to the line. - - Reflow the line to get the best formatting after the item is - inserted. The bracket depth indicates if the item is being - inserted inside of a container or not. - - """ - if self._prev_item and self._prev_item.is_string and item.is_string: - # Place consecutive string literals on separate lines. - self._lines.append(self._LineBreak()) - self._lines.append(self._Indent(indent_amt)) - - item_text = unicode(item) - if self._lines and self._bracket_depth: - # Adding the item into a container. - self._prevent_default_initializer_splitting(item, indent_amt) - - if item_text in '.,)]}': - self._split_after_delimiter(item, indent_amt) - - elif self._lines and not self.line_empty(): - # Adding the item outside of a container. - if self.fits_on_current_line(len(item_text)): - self._enforce_space(item) - - else: - # Line break for the new item. - self._lines.append(self._LineBreak()) - self._lines.append(self._Indent(indent_amt)) - - self._lines.append(item) - self._prev_item, self._prev_prev_item = item, self._prev_item - - if item_text in '([{': - self._bracket_depth += 1 - - elif item_text in '}])': - self._bracket_depth -= 1 - assert self._bracket_depth >= 0 - - def _add_container(self, container, indent_amt, break_after_open_bracket): - actual_indent = indent_amt + 1 - - if ( - unicode(self._prev_item) != '=' and - not self.line_empty() and - not self.fits_on_current_line( - container.size + self._bracket_depth + 2) - ): - - if unicode(container)[0] == '(' and self._prev_item.is_name: - # Don't split before the opening bracket of a call. - break_after_open_bracket = True - actual_indent = indent_amt + 4 - elif ( - break_after_open_bracket or - unicode(self._prev_item) not in '([{' - ): - # If the container doesn't fit on the current line and the - # current line isn't empty, place the container on the next - # line. - self._lines.append(self._LineBreak()) - self._lines.append(self._Indent(indent_amt)) - break_after_open_bracket = False - else: - actual_indent = self.current_size() + 1 - break_after_open_bracket = False - - if isinstance(container, (ListComprehension, IfExpression)): - actual_indent = indent_amt - - # Increase the continued indentation only if recursing on a - # container. - container.reflow(self, ' ' * actual_indent, - break_after_open_bracket=break_after_open_bracket) - - def _prevent_default_initializer_splitting(self, item, indent_amt): - """Prevent splitting between a default initializer. - - When there is a default initializer, it's best to keep it all on - the same line. It's nicer and more readable, even if it goes - over the maximum allowable line length. This goes back along the - current line to determine if we have a default initializer, and, - if so, to remove extraneous whitespaces and add a line - break/indent before it if needed. - - """ - if unicode(item) == '=': - # This is the assignment in the initializer. Just remove spaces for - # now. - self._delete_whitespace() - return - - if (not self._prev_item or not self._prev_prev_item or - unicode(self._prev_item) != '='): - return - - self._delete_whitespace() - prev_prev_index = self._lines.index(self._prev_prev_item) - - if ( - isinstance(self._lines[prev_prev_index - 1], self._Indent) or - self.fits_on_current_line(item.size + 1) - ): - # The default initializer is already the only item on this line. - # Don't insert a newline here. - return - - # Replace the space with a newline/indent combo. - if isinstance(self._lines[prev_prev_index - 1], self._Space): - del self._lines[prev_prev_index - 1] - - self.add_line_break_at(self._lines.index(self._prev_prev_item), - indent_amt) - - def _split_after_delimiter(self, item, indent_amt): - """Split the line only after a delimiter.""" - self._delete_whitespace() - - if self.fits_on_current_line(item.size): - return - - last_space = None - for current_item in reversed(self._lines): - if ( - last_space and - (not isinstance(current_item, Atom) or - not current_item.is_colon) - ): - break - else: - last_space = None - if isinstance(current_item, self._Space): - last_space = current_item - if isinstance(current_item, (self._LineBreak, self._Indent)): - return - - if not last_space: - return - - self.add_line_break_at(self._lines.index(last_space), indent_amt) - - def _enforce_space(self, item): - """Enforce a space in certain situations. - - There are cases where we will want a space where normally we - wouldn't put one. This just enforces the addition of a space. - - """ - if isinstance(self._lines[-1], - (self._Space, self._LineBreak, self._Indent)): - return - - if not self._prev_item: - return - - item_text = unicode(item) - prev_text = unicode(self._prev_item) - - # Prefer a space around a '.' in an import statement, and between the - # 'import' and '('. - if ( - (item_text == '.' and prev_text == 'from') or - (item_text == 'import' and prev_text == '.') or - (item_text == '(' and prev_text == 'import') - ): - self._lines.append(self._Space()) - - def _delete_whitespace(self): - """Delete all whitespace from the end of the line.""" - while isinstance(self._lines[-1], (self._Space, self._LineBreak, - self._Indent)): - del self._lines[-1] - - -class Atom(object): - - """The smallest unbreakable unit that can be reflowed.""" - - def __init__(self, atom): - self._atom = atom - - def __repr__(self): - return self._atom.token_string - - def __len__(self): - return self.size - - def reflow( - self, reflowed_lines, continued_indent, extent, - break_after_open_bracket=False, - is_list_comp_or_if_expr=False, - next_is_dot=False - ): - if self._atom.token_type == tokenize.COMMENT: - reflowed_lines.add_comment(self) - return - - total_size = extent if extent else self.size - - if self._atom.token_string not in ',:([{}])': - # Some atoms will need an extra 1-sized space token after them. - total_size += 1 - - prev_item = reflowed_lines.previous_item() - if ( - not is_list_comp_or_if_expr and - not reflowed_lines.fits_on_current_line(total_size) and - not (next_is_dot and - reflowed_lines.fits_on_current_line(self.size + 1)) and - not reflowed_lines.line_empty() and - not self.is_colon and - not (prev_item and prev_item.is_name and - unicode(self) == '(') - ): - # Start a new line if there is already something on the line and - # adding this atom would make it go over the max line length. - reflowed_lines.add_line_break(continued_indent) - else: - reflowed_lines.add_space_if_needed(unicode(self)) - - reflowed_lines.add(self, len(continued_indent), - break_after_open_bracket) - - def emit(self): - return self.__repr__() - - @property - def is_keyword(self): - return keyword.iskeyword(self._atom.token_string) - - @property - def is_string(self): - return self._atom.token_type == tokenize.STRING - - @property - def is_name(self): - return self._atom.token_type == tokenize.NAME - - @property - def is_number(self): - return self._atom.token_type == tokenize.NUMBER - - @property - def is_comma(self): - return self._atom.token_string == ',' - - @property - def is_colon(self): - return self._atom.token_string == ':' - - @property - def size(self): - return len(self._atom.token_string) - - -class Container(object): - - """Base class for all container types.""" - - def __init__(self, items): - self._items = items - - def __repr__(self): - string = '' - last_was_keyword = False - - for item in self._items: - if item.is_comma: - string += ', ' - elif item.is_colon: - string += ': ' - else: - item_string = unicode(item) - if ( - string and - (last_was_keyword or - (not string.endswith(tuple('([{,.:}]) ')) and - not item_string.startswith(tuple('([{,.:}])')))) - ): - string += ' ' - string += item_string - - last_was_keyword = item.is_keyword - return string - - def __iter__(self): - for element in self._items: - yield element - - def __getitem__(self, idx): - return self._items[idx] - - def reflow(self, reflowed_lines, continued_indent, - break_after_open_bracket=False): - last_was_container = False - for (index, item) in enumerate(self._items): - next_item = get_item(self._items, index + 1) - - if isinstance(item, Atom): - is_list_comp_or_if_expr = ( - isinstance(self, (ListComprehension, IfExpression))) - item.reflow(reflowed_lines, continued_indent, - self._get_extent(index), - is_list_comp_or_if_expr=is_list_comp_or_if_expr, - next_is_dot=(next_item and - unicode(next_item) == '.')) - if last_was_container and item.is_comma: - reflowed_lines.add_line_break(continued_indent) - last_was_container = False - else: # isinstance(item, Container) - reflowed_lines.add(item, len(continued_indent), - break_after_open_bracket) - last_was_container = not isinstance(item, (ListComprehension, - IfExpression)) - - if ( - break_after_open_bracket and index == 0 and - # Prefer to keep empty containers together instead of - # separating them. - unicode(item) == self.open_bracket and - (not next_item or unicode(next_item) != self.close_bracket) and - (len(self._items) != 3 or not isinstance(next_item, Atom)) - ): - reflowed_lines.add_line_break(continued_indent) - break_after_open_bracket = False - else: - next_next_item = get_item(self._items, index + 2) - if ( - unicode(item) not in ['.', '%', 'in'] and - next_item and not isinstance(next_item, Container) and - unicode(next_item) != ':' and - next_next_item and (not isinstance(next_next_item, Atom) or - unicode(next_item) == 'not') and - not reflowed_lines.line_empty() and - not reflowed_lines.fits_on_current_line( - self._get_extent(index + 1) + 2) - ): - reflowed_lines.add_line_break(continued_indent) - - def _get_extent(self, index): - """The extent of the full element. - - E.g., the length of a function call or keyword. - - """ - extent = 0 - prev_item = get_item(self._items, index - 1) - seen_dot = prev_item and unicode(prev_item) == '.' - while index < len(self._items): - item = get_item(self._items, index) - index += 1 - - if isinstance(item, (ListComprehension, IfExpression)): - break - - if isinstance(item, Container): - if prev_item and prev_item.is_name: - if seen_dot: - extent += 1 - else: - extent += item.size - - prev_item = item - continue - elif (unicode(item) not in ['.', '=', ':', 'not'] and - not item.is_name and not item.is_string): - break - - if unicode(item) == '.': - seen_dot = True - - extent += item.size - prev_item = item - - return extent - - @property - def is_string(self): - return False - - @property - def size(self): - return len(self.__repr__()) - - @property - def is_keyword(self): - return False - - @property - def is_name(self): - return False - - @property - def is_comma(self): - return False - - @property - def is_colon(self): - return False - - @property - def open_bracket(self): - return None - - @property - def close_bracket(self): - return None - - -class Tuple(Container): - - """A high-level representation of a tuple.""" - - @property - def open_bracket(self): - return '(' - - @property - def close_bracket(self): - return ')' - - -class List(Container): - - """A high-level representation of a list.""" - - @property - def open_bracket(self): - return '[' - - @property - def close_bracket(self): - return ']' - - -class DictOrSet(Container): - - """A high-level representation of a dictionary or set.""" - - @property - def open_bracket(self): - return '{' - - @property - def close_bracket(self): - return '}' - - -class ListComprehension(Container): - - """A high-level representation of a list comprehension.""" - - @property - def size(self): - length = 0 - for item in self._items: - if isinstance(item, IfExpression): - break - length += item.size - return length - - -class IfExpression(Container): - - """A high-level representation of an if-expression.""" - - -def _parse_container(tokens, index, for_or_if=None): - """Parse a high-level container, such as a list, tuple, etc.""" - - # Store the opening bracket. - items = [Atom(Token(*tokens[index]))] - index += 1 - - num_tokens = len(tokens) - while index < num_tokens: - tok = Token(*tokens[index]) - - if tok.token_string in ',)]}': - # First check if we're at the end of a list comprehension or - # if-expression. Don't add the ending token as part of the list - # comprehension or if-expression, because they aren't part of those - # constructs. - if for_or_if == 'for': - return (ListComprehension(items), index - 1) - - elif for_or_if == 'if': - return (IfExpression(items), index - 1) - - # We've reached the end of a container. - items.append(Atom(tok)) - - # If not, then we are at the end of a container. - if tok.token_string == ')': - # The end of a tuple. - return (Tuple(items), index) - - elif tok.token_string == ']': - # The end of a list. - return (List(items), index) - - elif tok.token_string == '}': - # The end of a dictionary or set. - return (DictOrSet(items), index) - - elif tok.token_string in '([{': - # A sub-container is being defined. - (container, index) = _parse_container(tokens, index) - items.append(container) - - elif tok.token_string == 'for': - (container, index) = _parse_container(tokens, index, 'for') - items.append(container) - - elif tok.token_string == 'if': - (container, index) = _parse_container(tokens, index, 'if') - items.append(container) - - else: - items.append(Atom(tok)) - - index += 1 - - return (None, None) - - -def _parse_tokens(tokens): - """Parse the tokens. - - This converts the tokens into a form where we can manipulate them - more easily. - - """ - - index = 0 - parsed_tokens = [] - - num_tokens = len(tokens) - while index < num_tokens: - tok = Token(*tokens[index]) - - assert tok.token_type != token.INDENT - if tok.token_type == tokenize.NEWLINE: - # There's only one newline and it's at the end. - break - - if tok.token_string in '([{': - (container, index) = _parse_container(tokens, index) - if not container: - return None - parsed_tokens.append(container) - else: - parsed_tokens.append(Atom(tok)) - - index += 1 - - return parsed_tokens - - -def _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line): - """Reflow the lines so that it looks nice.""" - - if unicode(parsed_tokens[0]) == 'def': - # A function definition gets indented a bit more. - continued_indent = indentation + ' ' * 2 * DEFAULT_INDENT_SIZE - else: - continued_indent = indentation + ' ' * DEFAULT_INDENT_SIZE - - break_after_open_bracket = not start_on_prefix_line - - lines = ReformattedLines(max_line_length) - lines.add_indent(len(indentation.lstrip('\r\n'))) - - if not start_on_prefix_line: - # If splitting after the opening bracket will cause the first element - # to be aligned weirdly, don't try it. - first_token = get_item(parsed_tokens, 0) - second_token = get_item(parsed_tokens, 1) - - if ( - first_token and second_token and - unicode(second_token)[0] == '(' and - len(indentation) + len(first_token) + 1 == len(continued_indent) - ): - return None - - for item in parsed_tokens: - lines.add_space_if_needed(unicode(item), equal=True) - - save_continued_indent = continued_indent - if start_on_prefix_line and isinstance(item, Container): - start_on_prefix_line = False - continued_indent = ' ' * (lines.current_size() + 1) - - item.reflow(lines, continued_indent, break_after_open_bracket) - continued_indent = save_continued_indent - - return lines.emit() - - -def _shorten_line_at_tokens_new(tokens, source, indentation, - max_line_length): - """Shorten the line taking its length into account. - - The input is expected to be free of newlines except for inside - multiline strings and at the end. - - """ - # Yield the original source so to see if it's a better choice than the - # shortened candidate lines we generate here. - yield indentation + source - - parsed_tokens = _parse_tokens(tokens) - - if parsed_tokens: - # Perform two reflows. The first one starts on the same line as the - # prefix. The second starts on the line after the prefix. - fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line=True) - if fixed and check_syntax(normalize_multiline(fixed.lstrip())): - yield fixed - - fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line=False) - if fixed and check_syntax(normalize_multiline(fixed.lstrip())): - yield fixed - - -def _shorten_line_at_tokens(tokens, source, indentation, indent_word, - key_token_strings, aggressive): - """Separate line by breaking at tokens in key_token_strings. - - The input is expected to be free of newlines except for inside - multiline strings and at the end. - - """ - offsets = [] - for (index, _t) in enumerate(token_offsets(tokens)): - (token_type, - token_string, - start_offset, - end_offset) = _t - - assert token_type != token.INDENT - - if token_string in key_token_strings: - # Do not break in containers with zero or one items. - unwanted_next_token = { - '(': ')', - '[': ']', - '{': '}'}.get(token_string) - if unwanted_next_token: - if ( - get_item(tokens, - index + 1, - default=[None, None])[1] == unwanted_next_token or - get_item(tokens, - index + 2, - default=[None, None])[1] == unwanted_next_token - ): - continue - - if ( - index > 2 and token_string == '(' and - tokens[index - 1][1] in ',(%[' - ): - # Don't split after a tuple start, or before a tuple start if - # the tuple is in a list. - continue - - if end_offset < len(source) - 1: - # Don't split right before newline. - offsets.append(end_offset) - else: - # Break at adjacent strings. These were probably meant to be on - # separate lines in the first place. - previous_token = get_item(tokens, index - 1) - if ( - token_type == tokenize.STRING and - previous_token and previous_token[0] == tokenize.STRING - ): - offsets.append(start_offset) - - current_indent = None - fixed = None - for line in split_at_offsets(source, offsets): - if fixed: - fixed += '\n' + current_indent + line - - for symbol in '([{': - if line.endswith(symbol): - current_indent += indent_word - else: - # First line. - fixed = line - assert not current_indent - current_indent = indent_word - - assert fixed is not None - - if check_syntax(normalize_multiline(fixed) - if aggressive > 1 else fixed): - return indentation + fixed - - return None - - -def token_offsets(tokens): - """Yield tokens and offsets.""" - end_offset = 0 - previous_end_row = 0 - previous_end_column = 0 - for t in tokens: - token_type = t[0] - token_string = t[1] - (start_row, start_column) = t[2] - (end_row, end_column) = t[3] - - # Account for the whitespace between tokens. - end_offset += start_column - if previous_end_row == start_row: - end_offset -= previous_end_column - - # Record the start offset of the token. - start_offset = end_offset - - # Account for the length of the token itself. - end_offset += len(token_string) - - yield (token_type, - token_string, - start_offset, - end_offset) - - previous_end_row = end_row - previous_end_column = end_column - - -def normalize_multiline(line): - """Normalize multiline-related code that will cause syntax error. - - This is for purposes of checking syntax. - - """ - if line.startswith('def ') and line.rstrip().endswith(':'): - return line + ' pass' - elif line.startswith('return '): - return 'def _(): ' + line - elif line.startswith('@'): - return line + 'def _(): pass' - elif line.startswith('class '): - return line + ' pass' - elif line.startswith(('if ', 'elif ', 'for ', 'while ')): - return line + ' pass' - - return line - - -def fix_whitespace(line, offset, replacement): - """Replace whitespace at offset and return fixed line.""" - # Replace escaped newlines too - left = line[:offset].rstrip('\n\r \t\\') - right = line[offset:].lstrip('\n\r \t\\') - if right.startswith('#'): - return line - - return left + replacement + right - - -def _execute_pep8(pep8_options, source): - """Execute pycodestyle via python method calls.""" - class QuietReport(pycodestyle.BaseReport): - - """Version of checker that does not print.""" - - def __init__(self, options): - super(QuietReport, self).__init__(options) - self.__full_error_results = [] - - def error(self, line_number, offset, text, check): - """Collect errors.""" - code = super(QuietReport, self).error(line_number, - offset, - text, - check) - if code: - self.__full_error_results.append( - {'id': code, - 'line': line_number, - 'column': offset + 1, - 'info': text}) - - def full_error_results(self): - """Return error results in detail. - - Results are in the form of a list of dictionaries. Each - dictionary contains 'id', 'line', 'column', and 'info'. - - """ - return self.__full_error_results - - checker = pycodestyle.Checker('', lines=source, reporter=QuietReport, - **pep8_options) - checker.check_all() - return checker.report.full_error_results() - - -def _remove_leading_and_normalize(line): - # ignore FF in first lstrip() - return line.lstrip(' \t\v').rstrip(CR + LF) + '\n' - - -class Reindenter(object): - - """Reindents badly-indented code to uniformly use four-space indentation. - - Released to the public domain, by Tim Peters, 03 October 2000. - - """ - - def __init__(self, input_text): - sio = io.StringIO(input_text) - source_lines = sio.readlines() - - self.string_content_line_numbers = multiline_string_lines(input_text) - - # File lines, rstripped & tab-expanded. Dummy at start is so - # that we can use tokenize's 1-based line numbering easily. - # Note that a line is all-blank iff it is a newline. - self.lines = [] - for line_number, line in enumerate(source_lines, start=1): - # Do not modify if inside a multiline string. - if line_number in self.string_content_line_numbers: - self.lines.append(line) - else: - # Only expand leading tabs. - self.lines.append(_get_indentation(line).expandtabs() + - _remove_leading_and_normalize(line)) - - self.lines.insert(0, None) - self.index = 1 # index into self.lines of next line - self.input_text = input_text - - def run(self, indent_size=DEFAULT_INDENT_SIZE): - """Fix indentation and return modified line numbers. - - Line numbers are indexed at 1. - - """ - if indent_size < 1: - return self.input_text - - try: - stats = _reindent_stats(tokenize.generate_tokens(self.getline)) - except (SyntaxError, tokenize.TokenError): - return self.input_text - # Remove trailing empty lines. - lines = self.lines - # Sentinel. - stats.append((len(lines), 0)) - # Map count of leading spaces to # we want. - have2want = {} - # Program after transformation. - after = [] - # Copy over initial empty lines -- there's nothing to do until - # we see a line with *something* on it. - i = stats[0][0] - after.extend(lines[1:i]) - for i in range(len(stats) - 1): - thisstmt, thislevel = stats[i] - nextstmt = stats[i + 1][0] - have = _leading_space_count(lines[thisstmt]) - want = thislevel * indent_size - if want < 0: - # A comment line. - if have: - # An indented comment line. If we saw the same - # indentation before, reuse what it most recently - # mapped to. - want = have2want.get(have, -1) - if want < 0: - # Then it probably belongs to the next real stmt. - for j in range(i + 1, len(stats) - 1): - jline, jlevel = stats[j] - if jlevel >= 0: - if have == _leading_space_count(lines[jline]): - want = jlevel * indent_size - break - # Maybe it's a hanging comment like this one, - if want < 0: - # in which case we should shift it like its base - # line got shifted. - for j in range(i - 1, -1, -1): - jline, jlevel = stats[j] - if jlevel >= 0: - want = (have + _leading_space_count( - after[jline - 1]) - - _leading_space_count(lines[jline])) - break - if want < 0: - # Still no luck -- leave it alone. - want = have - else: - want = 0 - assert want >= 0 - have2want[have] = want - diff = want - have - if diff == 0 or have == 0: - after.extend(lines[thisstmt:nextstmt]) - else: - for line_number, line in enumerate(lines[thisstmt:nextstmt], - start=thisstmt): - if line_number in self.string_content_line_numbers: - after.append(line) - elif diff > 0: - if line == '\n': - after.append(line) - else: - after.append(' ' * diff + line) - else: - remove = min(_leading_space_count(line), -diff) - after.append(line[remove:]) - - return ''.join(after) - - def getline(self): - """Line-getter for tokenize.""" - if self.index >= len(self.lines): - line = '' - else: - line = self.lines[self.index] - self.index += 1 - return line - - -def _reindent_stats(tokens): - """Return list of (lineno, indentlevel) pairs. - - One for each stmt and comment line. indentlevel is -1 for comment - lines, as a signal that tokenize doesn't know what to do about them; - indeed, they're our headache! - - """ - find_stmt = 1 # Next token begins a fresh stmt? - level = 0 # Current indent level. - stats = [] - - for t in tokens: - token_type = t[0] - sline = t[2][0] - line = t[4] - - if token_type == tokenize.NEWLINE: - # A program statement, or ENDMARKER, will eventually follow, - # after some (possibly empty) run of tokens of the form - # (NL | COMMENT)* (INDENT | DEDENT+)? - find_stmt = 1 - - elif token_type == tokenize.INDENT: - find_stmt = 1 - level += 1 - - elif token_type == tokenize.DEDENT: - find_stmt = 1 - level -= 1 - - elif token_type == tokenize.COMMENT: - if find_stmt: - stats.append((sline, -1)) - # But we're still looking for a new stmt, so leave - # find_stmt alone. - - elif token_type == tokenize.NL: - pass - - elif find_stmt: - # This is the first "real token" following a NEWLINE, so it - # must be the first token of the next program statement, or an - # ENDMARKER. - find_stmt = 0 - if line: # Not endmarker. - stats.append((sline, level)) - - return stats - - -def _leading_space_count(line): - """Return number of leading spaces in line.""" - i = 0 - while i < len(line) and line[i] == ' ': - i += 1 - return i - - -def refactor_with_2to3(source_text, fixer_names, filename=''): - """Use lib2to3 to refactor the source. - - Return the refactored source code. - - """ - from lib2to3.refactor import RefactoringTool - fixers = ['lib2to3.fixes.fix_' + name for name in fixer_names] - tool = RefactoringTool(fixer_names=fixers, explicit=fixers) - - from lib2to3.pgen2 import tokenize as lib2to3_tokenize - try: - # The name parameter is necessary particularly for the "import" fixer. - return unicode(tool.refactor_string(source_text, name=filename)) - except lib2to3_tokenize.TokenError: - return source_text - - -def check_syntax(code): - """Return True if syntax is okay.""" - try: - return compile(code, '', 'exec', dont_inherit=True) - except (SyntaxError, TypeError, ValueError): - return False - - -def find_with_line_numbers(pattern, contents): - """A wrapper around 're.finditer' to find line numbers. - - Returns a list of line numbers where pattern was found in contents. - """ - matches = list(re.finditer(pattern, contents)) - if not matches: - return [] - - end = matches[-1].start() - - # -1 so a failed `rfind` maps to the first line. - newline_offsets = { - -1: 0 - } - for line_num, m in enumerate(re.finditer(r'\n', contents), 1): - offset = m.start() - if offset > end: - break - newline_offsets[offset] = line_num - - def get_line_num(match, contents): - """Get the line number of string in a files contents. - - Failing to find the newline is OK, -1 maps to 0 - - """ - newline_offset = contents.rfind('\n', 0, match.start()) - return newline_offsets[newline_offset] - - return [get_line_num(match, contents) + 1 for match in matches] - - -def get_disabled_ranges(source): - """Returns a list of tuples representing the disabled ranges. - - If disabled and no re-enable will disable for rest of file. - - """ - enable_line_nums = find_with_line_numbers(ENABLE_REGEX, source) - disable_line_nums = find_with_line_numbers(DISABLE_REGEX, source) - total_lines = len(re.findall("\n", source)) + 1 - - enable_commands = {} - for num in enable_line_nums: - enable_commands[num] = True - for num in disable_line_nums: - enable_commands[num] = False - - disabled_ranges = [] - currently_enabled = True - disabled_start = None - - for line, commanded_enabled in sorted(enable_commands.items()): - if currently_enabled is True and commanded_enabled is False: - disabled_start = line - currently_enabled = False - elif currently_enabled is False and commanded_enabled is True: - disabled_ranges.append((disabled_start, line)) - currently_enabled = True - - if currently_enabled is False: - disabled_ranges.append((disabled_start, total_lines)) - - return disabled_ranges - - -def filter_results(source, results, aggressive): - """Filter out spurious reports from pycodestyle. - - If aggressive is True, we allow possibly unsafe fixes (E711, E712). - - """ - non_docstring_string_line_numbers = multiline_string_lines( - source, include_docstrings=False) - all_string_line_numbers = multiline_string_lines( - source, include_docstrings=True) - - commented_out_code_line_numbers = commented_out_code_lines(source) - - # Filter out the disabled ranges - disabled_ranges = get_disabled_ranges(source) - if len(disabled_ranges) > 0: - results = [result for result in results - if any(result['line'] not in range(*disabled_range) - for disabled_range in disabled_ranges) - ] - - has_e901 = any(result['id'].lower() == 'e901' for result in results) - - for r in results: - issue_id = r['id'].lower() - - if r['line'] in non_docstring_string_line_numbers: - if issue_id.startswith(('e1', 'e501', 'w191')): - continue - - if r['line'] in all_string_line_numbers: - if issue_id in ['e501']: - continue - - # We must offset by 1 for lines that contain the trailing contents of - # multiline strings. - if not aggressive and (r['line'] + 1) in all_string_line_numbers: - # Do not modify multiline strings in non-aggressive mode. Remove - # trailing whitespace could break doctests. - if issue_id.startswith(('w29', 'w39')): - continue - - if aggressive <= 0: - if issue_id.startswith(('e711', 'e72', 'w6')): - continue - - if aggressive <= 1: - if issue_id.startswith(('e712', 'e713', 'e714')): - continue - - if aggressive <= 2: - if issue_id.startswith(('e704')): - continue - - if r['line'] in commented_out_code_line_numbers: - if issue_id.startswith(('e26', 'e501')): - continue - - # Do not touch indentation if there is a token error caused by - # incomplete multi-line statement. Otherwise, we risk screwing up the - # indentation. - if has_e901: - if issue_id.startswith(('e1', 'e7')): - continue - - yield r - - -def multiline_string_lines(source, include_docstrings=False): - """Return line numbers that are within multiline strings. - - The line numbers are indexed at 1. - - Docstrings are ignored. - - """ - line_numbers = set() - previous_token_type = '' - try: - for t in generate_tokens(source): - token_type = t[0] - start_row = t[2][0] - end_row = t[3][0] - - if token_type == tokenize.STRING and start_row != end_row: - if ( - include_docstrings or - previous_token_type != tokenize.INDENT - ): - # We increment by one since we want the contents of the - # string. - line_numbers |= set(range(1 + start_row, 1 + end_row)) - - previous_token_type = token_type - except (SyntaxError, tokenize.TokenError): - pass - - return line_numbers - - -def commented_out_code_lines(source): - """Return line numbers of comments that are likely code. - - Commented-out code is bad practice, but modifying it just adds even - more clutter. - - """ - line_numbers = [] - try: - for t in generate_tokens(source): - token_type = t[0] - token_string = t[1] - start_row = t[2][0] - line = t[4] - - # Ignore inline comments. - if not line.lstrip().startswith('#'): - continue - - if token_type == tokenize.COMMENT: - stripped_line = token_string.lstrip('#').strip() - with warnings.catch_warnings(): - # ignore SyntaxWarning in Python3.8+ - # refs: - # https://bugs.python.org/issue15248 - # https://docs.python.org/3.8/whatsnew/3.8.html#other-language-changes - warnings.filterwarnings("ignore", category=SyntaxWarning) - if ( - ' ' in stripped_line and - '#' not in stripped_line and - check_syntax(stripped_line) - ): - line_numbers.append(start_row) - except (SyntaxError, tokenize.TokenError): - pass - - return line_numbers - - -def shorten_comment(line, max_line_length, last_comment=False): - """Return trimmed or split long comment line. - - If there are no comments immediately following it, do a text wrap. - Doing this wrapping on all comments in general would lead to jagged - comment text. - - """ - assert len(line) > max_line_length - line = line.rstrip() - - # PEP 8 recommends 72 characters for comment text. - indentation = _get_indentation(line) + '# ' - max_line_length = min(max_line_length, - len(indentation) + 72) - - MIN_CHARACTER_REPEAT = 5 - if ( - len(line) - len(line.rstrip(line[-1])) >= MIN_CHARACTER_REPEAT and - not line[-1].isalnum() - ): - # Trim comments that end with things like --------- - return line[:max_line_length] + '\n' - elif last_comment and re.match(r'\s*#+\s*\w+', line): - split_lines = textwrap.wrap(line.lstrip(' \t#'), - initial_indent=indentation, - subsequent_indent=indentation, - width=max_line_length, - break_long_words=False, - break_on_hyphens=False) - return '\n'.join(split_lines) + '\n' - - return line + '\n' - - -def normalize_line_endings(lines, newline): - """Return fixed line endings. - - All lines will be modified to use the most common line ending. - - """ - return [line.rstrip('\n\r') + newline for line in lines] - - -def mutual_startswith(a, b): - return b.startswith(a) or a.startswith(b) - - -def code_match(code, select, ignore): - if ignore: - assert not isinstance(ignore, unicode) - for ignored_code in [c.strip() for c in ignore]: - if mutual_startswith(code.lower(), ignored_code.lower()): - return False - - if select: - assert not isinstance(select, unicode) - for selected_code in [c.strip() for c in select]: - if mutual_startswith(code.lower(), selected_code.lower()): - return True - return False - - return True - - -def fix_code(source, options=None, encoding=None, apply_config=False): - """Return fixed source code. - - "encoding" will be used to decode "source" if it is a byte string. - - """ - options = _get_options(options, apply_config) - - if not isinstance(source, unicode): - source = source.decode(encoding or get_encoding()) - - sio = io.StringIO(source) - return fix_lines(sio.readlines(), options=options) - - -def _get_options(raw_options, apply_config): - """Return parsed options.""" - if not raw_options: - return parse_args([''], apply_config=apply_config) - - if isinstance(raw_options, dict): - options = parse_args([''], apply_config=apply_config) - for name, value in raw_options.items(): - if not hasattr(options, name): - raise ValueError("No such option '{}'".format(name)) - - # Check for very basic type errors. - expected_type = type(getattr(options, name)) - if not isinstance(expected_type, (str, unicode)): - if isinstance(value, (str, unicode)): - raise ValueError( - "Option '{}' should not be a string".format(name)) - setattr(options, name, value) - else: - options = raw_options - - return options - - -def fix_lines(source_lines, options, filename=''): - """Return fixed source code.""" - # Transform everything to line feed. Then change them back to original - # before returning fixed source code. - original_newline = find_newline(source_lines) - tmp_source = ''.join(normalize_line_endings(source_lines, '\n')) - - # Keep a history to break out of cycles. - previous_hashes = set() - - if options.line_range: - # Disable "apply_local_fixes()" for now due to issue #175. - fixed_source = tmp_source - else: - pep8_options = { - 'ignore': options.ignore, - 'select': options.select, - 'max_line_length': options.max_line_length, - 'hang_closing': options.hang_closing, - } - sio = io.StringIO(tmp_source) - contents = sio.readlines() - results = _execute_pep8(pep8_options, contents) - codes = {result['id'] for result in results - if result['id'] in SELECTED_GLOBAL_FIXED_METHOD_CODES} - # Apply global fixes only once (for efficiency). - fixed_source = apply_global_fixes(tmp_source, - options, - filename=filename, - codes=codes) - - passes = 0 - long_line_ignore_cache = set() - while hash(fixed_source) not in previous_hashes: - if options.pep8_passes >= 0 and passes > options.pep8_passes: - break - passes += 1 - - previous_hashes.add(hash(fixed_source)) - - tmp_source = copy.copy(fixed_source) - - fix = FixPEP8( - filename, - options, - contents=tmp_source, - long_line_ignore_cache=long_line_ignore_cache) - - fixed_source = fix.fix() - - sio = io.StringIO(fixed_source) - return ''.join(normalize_line_endings(sio.readlines(), original_newline)) - - -def fix_file(filename, options=None, output=None, apply_config=False): - if not options: - options = parse_args([filename], apply_config=apply_config) - - original_source = readlines_from_file(filename) - - fixed_source = original_source - - if options.in_place or options.diff or output: - encoding = detect_encoding(filename) - - if output: - output = LineEndingWrapper(wrap_output(output, encoding=encoding)) - - fixed_source = fix_lines(fixed_source, options, filename=filename) - - if options.diff: - new = io.StringIO(fixed_source) - new = new.readlines() - diff = get_diff_text(original_source, new, filename) - if output: - output.write(diff) - output.flush() - elif options.jobs > 1: - diff = diff.encode(encoding) - return diff - elif options.in_place: - original = "".join(original_source).splitlines() - fixed = fixed_source.splitlines() - original_source_last_line = ( - original_source[-1].split("\n")[-1] if original_source else "" - ) - fixed_source_last_line = fixed_source.split("\n")[-1] - if original != fixed or ( - original_source_last_line != fixed_source_last_line - ): - with open_with_encoding(filename, 'w', encoding=encoding) as fp: - fp.write(fixed_source) - return fixed_source - return None - else: - if output: - output.write(fixed_source) - output.flush() - return fixed_source - - -def global_fixes(): - """Yield multiple (code, function) tuples.""" - for function in list(globals().values()): - if inspect.isfunction(function): - arguments = _get_parameters(function) - if arguments[:1] != ['source']: - continue - - code = extract_code_from_function(function) - if code: - yield (code, function) - - -def _get_parameters(function): - # pylint: disable=deprecated-method - if sys.version_info.major >= 3: - # We need to match "getargspec()", which includes "self" as the first - # value for methods. - # https://bugs.python.org/issue17481#msg209469 - if inspect.ismethod(function): - function = function.__func__ - - return list(inspect.signature(function).parameters) - else: - return inspect.getargspec(function)[0] - - -def apply_global_fixes(source, options, where='global', filename='', - codes=None): - """Run global fixes on source code. - - These are fixes that only need be done once (unlike those in - FixPEP8, which are dependent on pycodestyle). - - """ - if codes is None: - codes = [] - if any(code_match(code, select=options.select, ignore=options.ignore) - for code in ['E101', 'E111']): - source = reindent(source, - indent_size=options.indent_size) - - for (code, function) in global_fixes(): - if code.upper() in SELECTED_GLOBAL_FIXED_METHOD_CODES \ - and code.upper() not in codes: - continue - if code_match(code, select=options.select, ignore=options.ignore): - if options.verbose: - print('---> Applying {} fix for {}'.format(where, - code.upper()), - file=sys.stderr) - source = function(source, - aggressive=options.aggressive) - - source = fix_2to3(source, - aggressive=options.aggressive, - select=options.select, - ignore=options.ignore, - filename=filename, - where=where, - verbose=options.verbose) - - return source - - -def extract_code_from_function(function): - """Return code handled by function.""" - if not function.__name__.startswith('fix_'): - return None - - code = re.sub('^fix_', '', function.__name__) - if not code: - return None - - try: - int(code[1:]) - except ValueError: - return None - - return code - - -def _get_package_version(): - packages = ["pycodestyle: {}".format(pycodestyle.__version__)] - return ", ".join(packages) - - -def create_parser(): - """Return command-line parser.""" - parser = argparse.ArgumentParser(description=docstring_summary(__doc__), - prog='autopep8') - parser.add_argument('--version', action='version', - version='%(prog)s {} ({})'.format( - __version__, _get_package_version())) - parser.add_argument('-v', '--verbose', action='count', - default=0, - help='print verbose messages; ' - 'multiple -v result in more verbose messages') - parser.add_argument('-d', '--diff', action='store_true', - help='print the diff for the fixed source') - parser.add_argument('-i', '--in-place', action='store_true', - help='make changes to files in place') - parser.add_argument('--global-config', metavar='filename', - default=DEFAULT_CONFIG, - help='path to a global pep8 config file; if this file ' - 'does not exist then this is ignored ' - '(default: {})'.format(DEFAULT_CONFIG)) - parser.add_argument('--ignore-local-config', action='store_true', - help="don't look for and apply local config files; " - 'if not passed, defaults are updated with any ' - "config files in the project's root directory") - parser.add_argument('-r', '--recursive', action='store_true', - help='run recursively over directories; ' - 'must be used with --in-place or --diff') - parser.add_argument('-j', '--jobs', type=int, metavar='n', default=1, - help='number of parallel jobs; ' - 'match CPU count if value is less than 1') - parser.add_argument('-p', '--pep8-passes', metavar='n', - default=-1, type=int, - help='maximum number of additional pep8 passes ' - '(default: infinite)') - parser.add_argument('-a', '--aggressive', action='count', default=0, - help='enable non-whitespace changes; ' - 'multiple -a result in more aggressive changes') - parser.add_argument('--experimental', action='store_true', - help='enable experimental fixes') - parser.add_argument('--exclude', metavar='globs', - help='exclude file/directory names that match these ' - 'comma-separated globs') - parser.add_argument('--list-fixes', action='store_true', - help='list codes for fixes; ' - 'used by --ignore and --select') - parser.add_argument('--ignore', metavar='errors', default='', - help='do not fix these errors/warnings ' - '(default: {})'.format(DEFAULT_IGNORE)) - parser.add_argument('--select', metavar='errors', default='', - help='fix only these errors/warnings (e.g. E4,W)') - parser.add_argument('--max-line-length', metavar='n', default=79, type=int, - help='set maximum allowed line length ' - '(default: %(default)s)') - parser.add_argument('--line-range', '--range', metavar='line', - default=None, type=int, nargs=2, - help='only fix errors found within this inclusive ' - 'range of line numbers (e.g. 1 99); ' - 'line numbers are indexed at 1') - parser.add_argument('--indent-size', default=DEFAULT_INDENT_SIZE, - type=int, help=argparse.SUPPRESS) - parser.add_argument('--hang-closing', action='store_true', - help='hang-closing option passed to pycodestyle') - parser.add_argument('--exit-code', action='store_true', - help='change to behavior of exit code.' - ' default behavior of return value, 0 is no ' - 'differences, 1 is error exit. return 2 when' - ' add this option. 2 is exists differences.') - parser.add_argument('files', nargs='*', - help="files to format or '-' for standard in") - - return parser - - -def _expand_codes(codes, ignore_codes): - """expand to individual E/W codes""" - ret = set() - - is_conflict = False - if all( - any( - conflicting_code.startswith(code) - for code in codes - ) - for conflicting_code in CONFLICTING_CODES - ): - is_conflict = True - - is_ignore_w503 = "W503" in ignore_codes - is_ignore_w504 = "W504" in ignore_codes - - for code in codes: - if code == "W": - if is_ignore_w503 and is_ignore_w504: - ret.update({"W1", "W2", "W3", "W505", "W6"}) - elif is_ignore_w503: - ret.update({"W1", "W2", "W3", "W504", "W505", "W6"}) - else: - ret.update({"W1", "W2", "W3", "W503", "W505", "W6"}) - elif code in ("W5", "W50"): - if is_ignore_w503 and is_ignore_w504: - ret.update({"W505"}) - elif is_ignore_w503: - ret.update({"W504", "W505"}) - else: - ret.update({"W503", "W505"}) - elif not (code in ("W503", "W504") and is_conflict): - ret.add(code) - - return ret - - -def parse_args(arguments, apply_config=False): - """Parse command-line options.""" - parser = create_parser() - args = parser.parse_args(arguments) - - if not args.files and not args.list_fixes: - parser.error('incorrect number of arguments') - - args.files = [decode_filename(name) for name in args.files] - - if apply_config: - parser = read_config(args, parser) - # prioritize settings when exist pyproject.toml's tool.autopep8 section - try: - parser_with_pyproject_toml = read_pyproject_toml(args, parser) - except Exception: - parser_with_pyproject_toml = None - if parser_with_pyproject_toml: - parser = parser_with_pyproject_toml - args = parser.parse_args(arguments) - args.files = [decode_filename(name) for name in args.files] - - if '-' in args.files: - if len(args.files) > 1: - parser.error('cannot mix stdin and regular files') - - if args.diff: - parser.error('--diff cannot be used with standard input') - - if args.in_place: - parser.error('--in-place cannot be used with standard input') - - if args.recursive: - parser.error('--recursive cannot be used with standard input') - - if len(args.files) > 1 and not (args.in_place or args.diff): - parser.error('autopep8 only takes one filename as argument ' - 'unless the "--in-place" or "--diff" args are ' - 'used') - - if args.recursive and not (args.in_place or args.diff): - parser.error('--recursive must be used with --in-place or --diff') - - if args.in_place and args.diff: - parser.error('--in-place and --diff are mutually exclusive') - - if args.max_line_length <= 0: - parser.error('--max-line-length must be greater than 0') - - if args.select: - args.select = _expand_codes( - _split_comma_separated(args.select), - (_split_comma_separated(args.ignore) if args.ignore else []) - ) - - if args.ignore: - args.ignore = _split_comma_separated(args.ignore) - if all( - not any( - conflicting_code.startswith(ignore_code) - for ignore_code in args.ignore - ) - for conflicting_code in CONFLICTING_CODES - ): - args.ignore.update(CONFLICTING_CODES) - elif not args.select: - if args.aggressive: - # Enable everything by default if aggressive. - args.select = {'E', 'W1', 'W2', 'W3', 'W6'} - else: - args.ignore = _split_comma_separated(DEFAULT_IGNORE) - - if args.exclude: - args.exclude = _split_comma_separated(args.exclude) - else: - args.exclude = {} - - if args.jobs < 1: - # Do not import multiprocessing globally in case it is not supported - # on the platform. - import multiprocessing - args.jobs = multiprocessing.cpu_count() - - if args.jobs > 1 and not (args.in_place or args.diff): - parser.error('parallel jobs requires --in-place') - - if args.line_range: - if args.line_range[0] <= 0: - parser.error('--range must be positive numbers') - if args.line_range[0] > args.line_range[1]: - parser.error('First value of --range should be less than or equal ' - 'to the second') - - return args - - -def _get_normalize_options(config, section, option_list): - for (k, _) in config.items(section): - norm_opt = k.lstrip('-').replace('-', '_') - if not option_list.get(norm_opt): - continue - opt_type = option_list[norm_opt] - if opt_type is int: - value = config.getint(section, k) - elif opt_type is bool: - value = config.getboolean(section, k) - else: - value = config.get(section, k) - yield norm_opt, k, value - - -def read_config(args, parser): - """Read both user configuration and local configuration.""" - config = SafeConfigParser() - - try: - config.read(args.global_config) - - if not args.ignore_local_config: - parent = tail = args.files and os.path.abspath( - os.path.commonprefix(args.files)) - while tail: - if config.read([os.path.join(parent, fn) - for fn in PROJECT_CONFIG]): - break - (parent, tail) = os.path.split(parent) - - defaults = {} - option_list = {o.dest: o.type or type(o.default) - for o in parser._actions} - - for section in ['pep8', 'pycodestyle', 'flake8']: - if not config.has_section(section): - continue - for norm_opt, k, value in _get_normalize_options(config, section, - option_list): - if args.verbose: - print("enable config: section={}, key={}, value={}".format( - section, k, value)) - defaults[norm_opt] = value - - parser.set_defaults(**defaults) - except Error: - # Ignore for now. - pass - - return parser - - -def read_pyproject_toml(args, parser): - """Read pyproject.toml and load configuration.""" - config = None - - if os.path.exists(args.global_config): - with open(args.global_config) as fp: - config = toml.load(fp) - - if not args.ignore_local_config: - parent = tail = args.files and os.path.abspath( - os.path.commonprefix(args.files)) - while tail: - pyproject_toml = os.path.join(parent, "pyproject.toml") - if os.path.exists(pyproject_toml): - with open(pyproject_toml) as fp: - config = toml.load(fp) - break - (parent, tail) = os.path.split(parent) - - if not config: - return None - - if config.get("tool", {}).get("autopep8") is None: - return None - - config = config.get("tool").get("autopep8") - - defaults = {} - option_list = {o.dest: o.type or type(o.default) - for o in parser._actions} - - TUPLED_OPTIONS = ("ignore", "select") - for (k, v) in config.items(): - norm_opt = k.lstrip('-').replace('-', '_') - if not option_list.get(norm_opt): - continue - if type(v) in (list, tuple) and norm_opt in TUPLED_OPTIONS: - value = ",".join(v) - else: - value = v - if args.verbose: - print("enable pyproject.toml config: " - "key={}, value={}".format(k, value)) - defaults[norm_opt] = value - - if defaults: - # set value when exists key-value in defaults dict - parser.set_defaults(**defaults) - - return parser - - -def _split_comma_separated(string): - """Return a set of strings.""" - return {text.strip() for text in string.split(',') if text.strip()} - - -def decode_filename(filename): - """Return Unicode filename.""" - if isinstance(filename, unicode): - return filename - - return filename.decode(sys.getfilesystemencoding()) - - -def supported_fixes(): - """Yield pep8 error codes that autopep8 fixes. - - Each item we yield is a tuple of the code followed by its - description. - - """ - yield ('E101', docstring_summary(reindent.__doc__)) - - instance = FixPEP8(filename=None, options=None, contents='') - for attribute in dir(instance): - code = re.match('fix_([ew][0-9][0-9][0-9])', attribute) - if code: - yield ( - code.group(1).upper(), - re.sub(r'\s+', ' ', - docstring_summary(getattr(instance, attribute).__doc__)) - ) - - for (code, function) in sorted(global_fixes()): - yield (code.upper() + (4 - len(code)) * ' ', - re.sub(r'\s+', ' ', docstring_summary(function.__doc__))) - - for code in sorted(CODE_TO_2TO3): - yield (code.upper() + (4 - len(code)) * ' ', - re.sub(r'\s+', ' ', docstring_summary(fix_2to3.__doc__))) - - -def docstring_summary(docstring): - """Return summary of docstring.""" - return docstring.split('\n')[0] if docstring else '' - - -def line_shortening_rank(candidate, indent_word, max_line_length, - experimental=False): - """Return rank of candidate. - - This is for sorting candidates. - - """ - if not candidate.strip(): - return 0 - - rank = 0 - lines = candidate.rstrip().split('\n') - - offset = 0 - if ( - not lines[0].lstrip().startswith('#') and - lines[0].rstrip()[-1] not in '([{' - ): - for (opening, closing) in ('()', '[]', '{}'): - # Don't penalize empty containers that aren't split up. Things like - # this "foo(\n )" aren't particularly good. - opening_loc = lines[0].find(opening) - closing_loc = lines[0].find(closing) - if opening_loc >= 0: - if closing_loc < 0 or closing_loc != opening_loc + 1: - offset = max(offset, 1 + opening_loc) - - current_longest = max(offset + len(x.strip()) for x in lines) - - rank += 4 * max(0, current_longest - max_line_length) - - rank += len(lines) - - # Too much variation in line length is ugly. - rank += 2 * standard_deviation(len(line) for line in lines) - - bad_staring_symbol = { - '(': ')', - '[': ']', - '{': '}'}.get(lines[0][-1]) - - if len(lines) > 1: - if ( - bad_staring_symbol and - lines[1].lstrip().startswith(bad_staring_symbol) - ): - rank += 20 - - for lineno, current_line in enumerate(lines): - current_line = current_line.strip() - - if current_line.startswith('#'): - continue - - for bad_start in ['.', '%', '+', '-', '/']: - if current_line.startswith(bad_start): - rank += 100 - - # Do not tolerate operators on their own line. - if current_line == bad_start: - rank += 1000 - - if ( - current_line.endswith(('.', '%', '+', '-', '/')) and - "': " in current_line - ): - rank += 1000 - - if current_line.endswith(('(', '[', '{', '.')): - # Avoid lonely opening. They result in longer lines. - if len(current_line) <= len(indent_word): - rank += 100 - - # Avoid the ugliness of ", (\n". - if ( - current_line.endswith('(') and - current_line[:-1].rstrip().endswith(',') - ): - rank += 100 - - # Avoid the ugliness of "something[\n" and something[index][\n. - if ( - current_line.endswith('[') and - len(current_line) > 1 and - (current_line[-2].isalnum() or current_line[-2] in ']') - ): - rank += 300 - - # Also avoid the ugliness of "foo.\nbar" - if current_line.endswith('.'): - rank += 100 - - if has_arithmetic_operator(current_line): - rank += 100 - - # Avoid breaking at unary operators. - if re.match(r'.*[(\[{]\s*[\-\+~]$', current_line.rstrip('\\ ')): - rank += 1000 - - if re.match(r'.*lambda\s*\*$', current_line.rstrip('\\ ')): - rank += 1000 - - if current_line.endswith(('%', '(', '[', '{')): - rank -= 20 - - # Try to break list comprehensions at the "for". - if current_line.startswith('for '): - rank -= 50 - - if current_line.endswith('\\'): - # If a line ends in \-newline, it may be part of a - # multiline string. In that case, we would like to know - # how long that line is without the \-newline. If it's - # longer than the maximum, or has comments, then we assume - # that the \-newline is an okay candidate and only - # penalize it a bit. - total_len = len(current_line) - lineno += 1 - while lineno < len(lines): - total_len += len(lines[lineno]) - - if lines[lineno].lstrip().startswith('#'): - total_len = max_line_length - break - - if not lines[lineno].endswith('\\'): - break - - lineno += 1 - - if total_len < max_line_length: - rank += 10 - else: - rank += 100 if experimental else 1 - - # Prefer breaking at commas rather than colon. - if ',' in current_line and current_line.endswith(':'): - rank += 10 - - # Avoid splitting dictionaries between key and value. - if current_line.endswith(':'): - rank += 100 - - rank += 10 * count_unbalanced_brackets(current_line) - - return max(0, rank) - - -def standard_deviation(numbers): - """Return standard deviation.""" - numbers = list(numbers) - if not numbers: - return 0 - mean = sum(numbers) / len(numbers) - return (sum((n - mean) ** 2 for n in numbers) / - len(numbers)) ** .5 - - -def has_arithmetic_operator(line): - """Return True if line contains any arithmetic operators.""" - for operator in pycodestyle.ARITHMETIC_OP: - if operator in line: - return True - - return False - - -def count_unbalanced_brackets(line): - """Return number of unmatched open/close brackets.""" - count = 0 - for opening, closing in ['()', '[]', '{}']: - count += abs(line.count(opening) - line.count(closing)) - - return count - - -def split_at_offsets(line, offsets): - """Split line at offsets. - - Return list of strings. - - """ - result = [] - - previous_offset = 0 - current_offset = 0 - for current_offset in sorted(offsets): - if current_offset < len(line) and previous_offset != current_offset: - result.append(line[previous_offset:current_offset].strip()) - previous_offset = current_offset - - result.append(line[current_offset:]) - - return result - - -class LineEndingWrapper(object): - - r"""Replace line endings to work with sys.stdout. - - It seems that sys.stdout expects only '\n' as the line ending, no matter - the platform. Otherwise, we get repeated line endings. - - """ - - def __init__(self, output): - self.__output = output - - def write(self, s): - self.__output.write(s.replace('\r\n', '\n').replace('\r', '\n')) - - def flush(self): - self.__output.flush() - - -def match_file(filename, exclude): - """Return True if file is okay for modifying/recursing.""" - base_name = os.path.basename(filename) - - if base_name.startswith('.'): - return False - - for pattern in exclude: - if fnmatch.fnmatch(base_name, pattern): - return False - if fnmatch.fnmatch(filename, pattern): - return False - - if not os.path.isdir(filename) and not is_python_file(filename): - return False - - return True - - -def find_files(filenames, recursive, exclude): - """Yield filenames.""" - while filenames: - name = filenames.pop(0) - if recursive and os.path.isdir(name): - for root, directories, children in os.walk(name): - filenames += [os.path.join(root, f) for f in children - if match_file(os.path.join(root, f), - exclude)] - directories[:] = [d for d in directories - if match_file(os.path.join(root, d), - exclude)] - else: - is_exclude_match = False - for pattern in exclude: - if fnmatch.fnmatch(name, pattern): - is_exclude_match = True - break - if not is_exclude_match: - yield name - - -def _fix_file(parameters): - """Helper function for optionally running fix_file() in parallel.""" - if parameters[1].verbose: - print('[file:{}]'.format(parameters[0]), file=sys.stderr) - try: - return fix_file(*parameters) - except IOError as error: - print(unicode(error), file=sys.stderr) - - -def fix_multiple_files(filenames, options, output=None): - """Fix list of files. - - Optionally fix files recursively. - - """ - results = [] - filenames = find_files(filenames, options.recursive, options.exclude) - if options.jobs > 1: - import multiprocessing - pool = multiprocessing.Pool(options.jobs) - ret = pool.map(_fix_file, [(name, options) for name in filenames]) - if options.diff: - for r in ret: - sys.stdout.write(r.decode()) - sys.stdout.flush() - results.extend([x for x in ret if x is not None]) - else: - for name in filenames: - ret = _fix_file((name, options, output)) - if ret is None: - continue - if options.diff: - if ret != '': - results.append(ret) - elif options.in_place: - results.append(ret) - else: - original_source = readlines_from_file(name) - if "".join(original_source).splitlines() != ret.splitlines(): - results.append(ret) - return results - - -def is_python_file(filename): - """Return True if filename is Python file.""" - if filename.endswith('.py'): - return True - - try: - with open_with_encoding( - filename, - limit_byte_check=MAX_PYTHON_FILE_DETECTION_BYTES) as f: - text = f.read(MAX_PYTHON_FILE_DETECTION_BYTES) - if not text: - return False - first_line = text.splitlines()[0] - except (IOError, IndexError): - return False - - if not PYTHON_SHEBANG_REGEX.match(first_line): - return False - - return True - - -def is_probably_part_of_multiline(line): - """Return True if line is likely part of a multiline string. - - When multiline strings are involved, pep8 reports the error as being - at the start of the multiline string, which doesn't work for us. - - """ - return ( - '"""' in line or - "'''" in line or - line.rstrip().endswith('\\') - ) - - -def wrap_output(output, encoding): - """Return output with specified encoding.""" - return codecs.getwriter(encoding)(output.buffer - if hasattr(output, 'buffer') - else output) - - -def get_encoding(): - """Return preferred encoding.""" - return locale.getpreferredencoding() or sys.getdefaultencoding() - - -def main(argv=None, apply_config=True): - """Command-line entry.""" - if argv is None: - argv = sys.argv - - try: - # Exit on broken pipe. - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - except AttributeError: # pragma: no cover - # SIGPIPE is not available on Windows. - pass - - try: - args = parse_args(argv[1:], apply_config=apply_config) - - if args.list_fixes: - for code, description in sorted(supported_fixes()): - print('{code} - {description}'.format( - code=code, description=description)) - return EXIT_CODE_OK - - if args.files == ['-']: - assert not args.in_place - - encoding = sys.stdin.encoding or get_encoding() - read_stdin = sys.stdin.read() - fixed_stdin = fix_code(read_stdin, args, encoding=encoding) - - # LineEndingWrapper is unnecessary here due to the symmetry between - # standard in and standard out. - wrap_output(sys.stdout, encoding=encoding).write(fixed_stdin) - - if hash(read_stdin) != hash(fixed_stdin): - if args.exit_code: - return EXIT_CODE_EXISTS_DIFF - else: - if args.in_place or args.diff: - args.files = list(set(args.files)) - else: - assert len(args.files) == 1 - assert not args.recursive - - results = fix_multiple_files(args.files, args, sys.stdout) - if args.diff: - ret = any([len(ret) != 0 for ret in results]) - else: - # with in-place option - ret = any([ret is not None for ret in results]) - if args.exit_code and ret: - return EXIT_CODE_EXISTS_DIFF - except KeyboardInterrupt: - return EXIT_CODE_ERROR # pragma: no cover - - -class CachedTokenizer(object): - - """A one-element cache around tokenize.generate_tokens(). - - Original code written by Ned Batchelder, in coverage.py. - - """ - - def __init__(self): - self.last_text = None - self.last_tokens = None - - def generate_tokens(self, text): - """A stand-in for tokenize.generate_tokens().""" - if text != self.last_text: - string_io = io.StringIO(text) - self.last_tokens = list( - tokenize.generate_tokens(string_io.readline) - ) - self.last_text = text - return self.last_tokens - - -_cached_tokenizer = CachedTokenizer() -generate_tokens = _cached_tokenizer.generate_tokens - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/INSTALLER b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/LICENSE.rst b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/LICENSE.rst deleted file mode 100644 index d12a8491..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/LICENSE.rst +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2014 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/env/lib/python3.8/site-packages/click-7.1.2.dist-info/METADATA b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/METADATA deleted file mode 100644 index 00d69749..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/METADATA +++ /dev/null @@ -1,102 +0,0 @@ -Metadata-Version: 2.1 -Name: click -Version: 7.1.2 -Summary: Composable command line interface toolkit -Home-page: https://palletsprojects.com/p/click/ -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -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 :: 3 -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* - -\$ 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 -U click - -.. _pip: https://pip.pypa.io/en/stable/quickstart/ - - -A Simple Example ----------------- - -.. 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(f"Hello, {name}!") - - if __name__ == '__main__': - hello() - -.. 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/ -- Releases: https://pypi.org/project/click/ -- Code: https://github.com/pallets/click -- Issue tracker: https://github.com/pallets/click/issues -- Test status: https://dev.azure.com/pallets/click/_build -- Official chat: https://discord.gg/t6rrQZH - - diff --git a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/RECORD b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/RECORD deleted file mode 100644 index 8fc797da..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/RECORD +++ /dev/null @@ -1,40 +0,0 @@ -click-7.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -click-7.1.2.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 -click-7.1.2.dist-info/METADATA,sha256=LrRgakZKV7Yg3qJqX_plu2WhFW81MzP3EqQmZhHIO8M,2868 -click-7.1.2.dist-info/RECORD,, -click-7.1.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -click-7.1.2.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 -click/__init__.py,sha256=FkyGDQ-cbiQxP_lxgUspyFYS48f2S_pTcfKPz-d_RMo,2463 -click/__pycache__/__init__.cpython-38.pyc,, -click/__pycache__/_bashcomplete.cpython-38.pyc,, -click/__pycache__/_compat.cpython-38.pyc,, -click/__pycache__/_termui_impl.cpython-38.pyc,, -click/__pycache__/_textwrap.cpython-38.pyc,, -click/__pycache__/_unicodefun.cpython-38.pyc,, -click/__pycache__/_winconsole.cpython-38.pyc,, -click/__pycache__/core.cpython-38.pyc,, -click/__pycache__/decorators.cpython-38.pyc,, -click/__pycache__/exceptions.cpython-38.pyc,, -click/__pycache__/formatting.cpython-38.pyc,, -click/__pycache__/globals.cpython-38.pyc,, -click/__pycache__/parser.cpython-38.pyc,, -click/__pycache__/termui.cpython-38.pyc,, -click/__pycache__/testing.cpython-38.pyc,, -click/__pycache__/types.cpython-38.pyc,, -click/__pycache__/utils.cpython-38.pyc,, -click/_bashcomplete.py,sha256=9J98IHQYmCAr2Jup6TDshUr5FJEen-AoQCZR0K5nKxQ,12309 -click/_compat.py,sha256=AoMaYnZ-3pwtNXuHtlb6_UXsayoG0QZiHKIRy2VFezc,24169 -click/_termui_impl.py,sha256=yNktUMAdjYOU1HMkq915jR3zgAzUNtGSQqSTSSMn3eQ,20702 -click/_textwrap.py,sha256=ajCzkzFly5tjm9foQ5N9_MOeaYJMBjAltuFa69n4iXY,1197 -click/_unicodefun.py,sha256=apLSNEBZgUsQNPMUv072zJ1swqnm0dYVT5TqcIWTt6w,4201 -click/_winconsole.py,sha256=6YDu6Rq1Wxx4w9uinBMK2LHvP83aerZM9GQurlk3QDo,10010 -click/core.py,sha256=V6DJzastGhrC6WTDwV9MSLwcJUdX2Uf1ypmgkjBdn_Y,77650 -click/decorators.py,sha256=3TvEO_BkaHl7k6Eh1G5eC7JK4LKPdpFqH9JP0QDyTlM,11215 -click/exceptions.py,sha256=3pQAyyMFzx5A3eV0Y27WtDTyGogZRbrC6_o5DjjKBbw,8118 -click/formatting.py,sha256=Wb4gqFEpWaKPgAbOvnkCl8p-bEZx5KpM5ZSByhlnJNk,9281 -click/globals.py,sha256=ht7u2kUGI08pAarB4e4yC8Lkkxy6gJfRZyzxEj8EbWQ,1501 -click/parser.py,sha256=mFK-k58JtPpqO0AC36WAr0t5UfzEw1mvgVSyn7WCe9M,15691 -click/termui.py,sha256=G7QBEKIepRIGLvNdGwBTYiEtSImRxvTO_AglVpyHH2s,23998 -click/testing.py,sha256=EUEsDUqNXFgCLhZ0ZFOROpaVDA5I_rijwnNPE6qICgA,12854 -click/types.py,sha256=wuubik4VqgqAw5dvbYFkDt-zSAx97y9TQXuXcVaRyQA,25045 -click/utils.py,sha256=4VEcJ7iEHwjnFuzEuRtkT99o5VG3zqSD7Q2CVzv13WU,15940 diff --git a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/WHEEL b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/WHEEL deleted file mode 100644 index ef99c6cf..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/top_level.txt b/env/lib/python3.8/site-packages/click-7.1.2.dist-info/top_level.txt deleted file mode 100644 index dca9a909..00000000 --- a/env/lib/python3.8/site-packages/click-7.1.2.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -click diff --git a/env/lib/python3.8/site-packages/click/__init__.py b/env/lib/python3.8/site-packages/click/__init__.py deleted file mode 100644 index 2b6008f2..00000000 --- a/env/lib/python3.8/site-packages/click/__init__.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -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. -""" -from .core import Argument -from .core import BaseCommand -from .core import Command -from .core import CommandCollection -from .core import Context -from .core import Group -from .core import MultiCommand -from .core import Option -from .core import Parameter -from .decorators import argument -from .decorators import command -from .decorators import confirmation_option -from .decorators import group -from .decorators import help_option -from .decorators import make_pass_decorator -from .decorators import option -from .decorators import pass_context -from .decorators import pass_obj -from .decorators import password_option -from .decorators import version_option -from .exceptions import Abort -from .exceptions import BadArgumentUsage -from .exceptions import BadOptionUsage -from .exceptions import BadParameter -from .exceptions import ClickException -from .exceptions import FileError -from .exceptions import MissingParameter -from .exceptions import NoSuchOption -from .exceptions import UsageError -from .formatting import HelpFormatter -from .formatting import wrap_text -from .globals import get_current_context -from .parser import OptionParser -from .termui import clear -from .termui import confirm -from .termui import echo_via_pager -from .termui import edit -from .termui import get_terminal_size -from .termui import getchar -from .termui import launch -from .termui import pause -from .termui import progressbar -from .termui import prompt -from .termui import secho -from .termui import style -from .termui import unstyle -from .types import BOOL -from .types import Choice -from .types import DateTime -from .types import File -from .types import FLOAT -from .types import FloatRange -from .types import INT -from .types import IntRange -from .types import ParamType -from .types import Path -from .types import STRING -from .types import Tuple -from .types import UNPROCESSED -from .types import UUID -from .utils import echo -from .utils import format_filename -from .utils import get_app_dir -from .utils import get_binary_stream -from .utils import get_os_args -from .utils import get_text_stream -from .utils import open_file - -# Controls if click should emit the warning about the use of unicode -# literals. -disable_unicode_literals_warning = False - -__version__ = "7.1.2" diff --git a/env/lib/python3.8/site-packages/click/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 59bab75c1ebafa71006bf64f1e1964a3fac4b6cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2746 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 diff --git a/env/lib/python3.8/site-packages/click/__pycache__/_compat.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/_compat.cpython-38.pyc deleted file mode 100644 index 5d2f203d27ee3d30bd33e089e692f1ad02401b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18860 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 diff --git a/env/lib/python3.8/site-packages/click/__pycache__/_termui_impl.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/_termui_impl.cpython-38.pyc deleted file mode 100644 index 424913af52b09e70ebaafb7d8a1e8c64ad394fa0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14270 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 diff --git a/env/lib/python3.8/site-packages/click/__pycache__/_unicodefun.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/_unicodefun.cpython-38.pyc deleted file mode 100644 index e437f62c170c52afc93c2cf4ceb8bf53ac492bb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3353 zcmb7GOOM;u73L)=ijrl=kMYE>1z{L*rszmT6QBblE@DjW!hzuqY6po06a>Y4C2>TN zntLzjAxi~Xci8~h72OmPkWIH;bkj}ImC>KTZC6=$QJ_HMe&FSRq305}3fzW*!jfEujOFs-VOv13Vre2&T@u0 zFLWVky*`Xoq_r#^b)qC`P&WGEAkBMGs!9js%BIqh)aoeF!_w=Ay(k{hH_o{z{WuT% zX*5vX^F@}>QkW)MNL=oojq~v&Nrf~gwj5ap^{&&GWM>k^dML(GwylIb6tW|-!%mv?I+GJU%(D;LI~@g%+c-Ch210d= znw@YZPQS?7laumB*iSOPUVJTMXl&&}40R1Ji}`kwxr`p4Z7>g`^USqfCNE+4e>?mW z?84!8YK__4VsNwEm|5})x8QQ;g#|~#;Ugx$M=RXnZt9L}bDLQ+TYJ3rg7&>HFsJ=3 zxRcz6I16~9qFyS#EBR3*vm_fBzvG}w^XNLFV3*t+aG^!41rK1npim;n`_=F*F9qMm zLXeCnxzz38=`c|N{)ZwuOwtpQA++x{;)uv4I*6kzNHQ&RUc@3$MNg+9=oJIp z&4LqL2q+%f!Lz&w)G#knjt!+n#En4Wcmhd5r?`1DSO-ne&t-LY<-b5_2{lzacz~U8 zF2Op(p>d>>JPVW%!BFdoy3?r~-=0KiDzuu&d>;l-Z3N*uR64K|1#>(~#i2;I>e7Ri z)Vj%2P6sT9G{k_n$P_iGJMp)tjlob;J0|XGkC(ReFc7-i_Mu| zanaZLyO`Na_JaMI8Hm0zy?Z}X09}PVjI>EcKv^R5Y%DTO`8LRNZW3S}`v~wogL1(K z?G?h;A{8fz3EZ*VG<9?vP5zWGjkGy@MxS2h8kcN7`b)6l0a10 zlPFaH%1#1c6lkx-=;vvgAJOcz;|?R45EXT&*$nWj?gWo^!+Vb&-Cara#?HORKV7d+ ze|1`yG*M6_0&W%)m=lm)sk73NIIoRsVhA8>P41i8_3ntqpBGzO6z=7Ou8HB!6s7lk<5axB`RI&>&nLc z<5)~cx6;lPid)e`;fsY*Wo<8?h^%z?9`4;Q&rtXiszh3p^`AYtFJ(?GA9Z($qN*Ha zu_$Z36D`0Q{HeKXDpY8lCK=XhREH;J4GAD*=_8e@hR}&PM>l8+a_R2pNe1MB^#w2M zD{IL!q*m+aMW&OnFs!#4l638QeHB8bvL=qTjO1-PXv@QHi=Z%E1#P#99yN?Zf~(Rc zak@<^!qxWM1^7~kcuo2z;i^9b{lgDISN#$%3$2`sV(Z%*>>QdqlwYj0Ft@Spp@Vl{ zVf>Bn(5}Z^r-|~6eRI0SJd|zE6l>30eSO@tTi@8PT+d}U*e2*S%^%hs`#)H(uSfDO zB-rxhO?>2g^rGTk*3n9jCz1ZP2QgiMIekhyYL=zxG5n9l=($qyW9s=;3ojoM`gY6l IFZ$R13ra`gD*ylh diff --git a/env/lib/python3.8/site-packages/click/__pycache__/_winconsole.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/_winconsole.cpython-38.pyc deleted file mode 100644 index 620161b929f2a3c7c8738ac60361cdfb2532590e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9477 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 JWMzVRwg6#qz{&ss diff --git a/env/lib/python3.8/site-packages/click/__pycache__/decorators.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/decorators.cpython-38.pyc deleted file mode 100644 index 1bac526bf9d212f4ed10d3896d21f01ad8de17f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11567 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 SYNc8^Te(nqt8%_}^Zx-yl^e_e diff --git a/env/lib/python3.8/site-packages/click/__pycache__/exceptions.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index 61b07171ebe1cfdb8538d78c274c21e5bcb113ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9127 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 diff --git a/env/lib/python3.8/site-packages/click/__pycache__/globals.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/globals.cpython-38.pyc deleted file mode 100644 index 12c2080a028d67ec0295ffc61031a27340a78f26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1899 zcmZuy&5s*36t`!RG@H#Xw513n4ld#=Xq!|*pejNLR8eU!5!x;S_L4Z`my9a?%nvL>K?J#h&PiUEJx2 zoyTOb{}RuW0WI5!ig@xUqHbO{H{QYTA%5ly>@NG3oKivGB|nhIq(y9C!$q*_>HCzp zzYQ@5wk3k6^a=fmWWkR_gm_7dKM4pq0$b?JFdGAl3auftEJ|dwVv))$oZBH|$FVdl z;u)I*D+~z64dd*LUofkB3>%LkF#qvUon~r&3Xx?Cty0Fbi?bLsG%nFAXQ|S_WSZlh z(pKIQ3p(Rgt^qIb$i|Bzi^j8@8#AqO&6t2lX>OHn{5c~lRmP<8j&dziu4QuJP%nyv zEtF<4BsplqOcBNIA+>9WVl`uDvBcF>E@O+2^-d(Rput#tw#--*^K2=zC6m^mMaTjQK-o-!j7jNq8b1v6kBeY0a-pfiU|`&hFzPYR^mu-QaqxP`WvYQpWox|nV? z7pFCs37;ob>;So6@FH;})fAu&UZ%M;!1(K&jNu$3cvNIortq!SO3#Mg?&aUuF7F<@ z%y6g>3&${G@UQ3LWY8`W&+N=^RmBv)eBTsMa>JM zoreFKj$)O<$UuawAPu9Xv{MbaGNU4sqZ}c`kn-%F0garGAX|?TIUnU0HdfhZ!v`ZH zE!;!96<>lGd90&lqUJm?!~CMWy#zb071iWy$4SOQXhPv0$E^!k1W z2TtA313{PMDtI1l$Q7kT1gPNf^3(4yr@+Z5gR>@tjc6JzJZ_<3NT;9!G*Ry(@C!OCfoRT2I|f2JF(rnvgShMpo^54m;u+xv&E z6l6T9Yl!0+gY5A(dZ@Ie7Je~O2^NP%!k1W~4i~j9{*|ArX0EE(k4-I2oM8!bB?iO+ zQ%Hn9bAs|FiBc2u0V`B|mU_sQ5+A3HsqkT?j7XW`? e>$+EWcE3!OC=&R}{i6A6`avh`z1?kh+y4M>tqK+Z diff --git a/env/lib/python3.8/site-packages/click/__pycache__/parser.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/parser.cpython-38.pyc deleted file mode 100644 index 93b9a93884cdf49b023ea9e1b83e33790798dc1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11888 zcmc&)O^h4YeV;E5hqK((Y9-5(J*7S5RG_zFu06B{iXL(_TBN_<{|&jz z)h6w&+?~hwJ@5U$Klsk#qHo~ytO^egKXsk^AV>#o$Rs8`pkQuk2z);-i~k^iBwUW*o@I==mAFaf#?xJHb+av*(TT%sq~bJCaer_V`(|5V7Tk)1Xb>cW zEJ$MXalid7HsW?T!d95n?GJl#KTb04)epK!@M^Ey-U$W?4z$(X+=^Aui*Lrg;9O^* z{BDBNC+#@M?hNB#D@<^@Wb;C>759b#CiKHBLq~uCtncCV{eg-bt3DtQ2g6>N1OP-f zC=V;6GMUr#t?|YZb~>1dbC*!%8+qLsoDPA|=X(hm z+!HSd@l5w<19-Uj^Q*VzC|}_B2C+i~#7YfR(2vtJ+>BFyGfrX^5`BE(>}6Qa$r@V$ zV4DV;ahAomGeQLi3pNLX2)E`nd@k(+wppO@Fyf`sQJmto8vL>Y@SUZ>ptJv)TdIpq zlVIac@P>*v2kK7n_G<8MsPu9AVK>R}#F38~JkZ;BvMs>v>Y$U|;+0Sj!3%i5H;vqLf>0MUT)e` zUmIKm#cJ z2^85MdOyL4`sIB+Zs&I7>{#j>xwUKFm$iGQY20{5`Wu!Gv*pkbwMT{xx(QaW0WU92)gE zAZg}qCQ>5Z8jN~Tun~hNk`#B2WIOP3>*D8I6Ur?@wWDZ8d zV0ue^<|tO=bAsjD;CfyG5bgsq;LlFC*8>;?IIXoo61P@m=31L{KmD-o;W>dPy@FyK z+=qJH@zlxO*fsWyca5tCYNoEeYb2)}BeQmV^+gjzW*Xne?5oE2q0f4(=&Z* z$y_qWk2f`?G)ZZzS9*hX*h^nr)k_q)cMeWuak90*=_D$ffXaLINy(x=w{AFB4Yh;; zDH>K`tzIt7X2Vj;=qwz*Mvot3+rQH5rdfN?AHMh%v{UZw8WzBR^ttw@E23L&?K?a=?_kLN)zhdQNoaD%YZ%2HOKCg7eaMpP@yN;z%2(b$ zvMGsk!r?WUtJ_9oM+Qe^9^inPv-T7ch4Bet3ZATX)365-hPyn4o}wbs^6+hH>97YL z#bw^bq>`!Xg12S!w5iUacMfCZBa*hyG1QXOy(%eGOZm*luUH3wNmEPFEABKD=OIaep1o z-olnC_chEFP+Hwo7f_$W0?%B-Bj^4LRG_s%Rn(9xSmiS<3eaJQD*qSa64CbjJNwV8^Y5-AKwMTH=CE==jTKZFGcWg{r08ij#}7Qoq~ zk(Q;a<5$j|J@9>^hr_txL%hU=*P$+i zl~9;hi^`@NjD|&pHyIXgoN#{OMo`N5cIY=0^>_3(BFWSvz*NI2Tzz--Su~3Z9EtW; zVFNIS$$43mGe(+v#U>V{wYztD|{J-=|@5@Doa*REpu^h2MPqDJWO zSEx|!G<9ia);+fD+ypHSCskNqRpBCUQp>&c1z33IuA5gO6Jh7&#*QRyMGeBQh1*`KkTBJ5>Nyle1=kwIhpEeJHeps~&E{Rq zNuNbwfO=fhv$Td=0zI8Jm#jJ-=tYZT{2L$BobY|Yc$ID zLkmOOTHB;E>xz;5Li#OG*Yl`>LS`dBlo8V1HTLd;Ubd}G=;_@G^|xsx*JTF1pxY14 zz+N)v%QB~eIlD3kl(ua}?w%D@AB7H?y$upI@^(GWF8RRPuHj9_w$FWpHfw7FweSUJ;9$L@NUYb6zM58ci_vEv^Fxz%w|Ez3Na65Nk+(fhp-}6o%0h`*0MQXD)Ct^m}>sDwMMl7g(hJ?ZZ^SDO&$C|z20oz7{M5j5%tGB1o&$( zj8%3=t)Z!CmK-?I%-T^1ycuIWqFrHXpRr8emfkjc=RTyPm+*+Vok`2;R9b3TxehG~ zy7mh1<F5bS4xpq_$4k5+TmZc;opOM}xS4inqq3+s@n%z>5P*O}kgbz=b@}VGv^RhyF zQe?OlncsygcSGO=DI!1?7(B4lam-dvvN$9`YF8M+x;<1c{tb7fQR@H^o-uxU2AY!U z_Wi5b8tuk>2D(?G00Hc45jm`gP)ZwqX;#B$*20@G6>iZ;6b}0n_EGO^)+y0R)=^hc ztXH-MJ?Mq`vkL|PHHK5Va^#&AsC9^DDEXz|Id!WpcyRG z@%wq=`;1u<@;oHKfyGoHTXJ>OY zpI5oV<0!ho@YGHaet?8U4|Mj_rUoHmUQuDtIHi|J2bIvoMMeCCs2_$KrNQ6hDb43n zVLfv2Tr+l9YdA+jY9AF+69#Ky&%fioyo6^ewjTl!(f<;j^nDcjAOd(!m14s|7##*R z%&kgvI`X0#YHs953jks@sz;0X_M)Ze7`|)Ka&#QuezX#u!1qFQGI|8xbrCsdin}wi!S`C6Xv$GQ2k0p2$c4!{qoq7=?RvWbHQ`spDQp8(ZkB-Sz|qzKeaAiY*f{GY+gKyOAT(p_yqAFa0B{{ zB=%68>TbdjjuD*^tAz$M3}D*RGvm6b&1~ypQKA-8)4Hh0CR6FaHytG%{u%vRs@iS^ ze-a$<#IW_v@gr}^E8o^Jx~YLHf_2XCsbLonkImhND028p@HXnXHE};Orjc{4LFt)O zCqmad@H^bd`PiLQ@6&U!@~XBM@$JA%TAFw{M=H5@#klc0dffxP@Q%=XUA(eNcn1pf z9O8>2-I? z$n}&t8WIR+j!pb@@F$cjLYiGL=4>Y@)SKN1DUl#}S=*d#M6NJ5OztrD+-ivp+iG2y zR<-Slj@cfqmbPm3B-E2=I*ClvYKfWKLcDmkgcobUH)#{~X5q-}(5P=1W zGN2>OfVvnkPqE|MEcTTSb^mYi><3?;n(h&-icHBwaya)EH%5 zF;9v^P=|3de)RX;>mfV3isd4u=&r&B)jUTFl~Dmi95kOr*2m(738&cOzb)BhnzVo_ zgp}8I-5=nW|4;H#>$o5st!;d1^O07W`T>i514Uq5Cyb}}`4khh7vK`g<1-IIb~q>fs?mSCPN8l0J^4L$}w3^lVc0 z!Kf2^T(vku%qXPNT<}RPqX$Ou?SgEHWalOSrIq@5aSGcG+ZsRdFJ&B;0dG>LxtUqZY!qp4xfCit{~z!e)|7#+BsbDo_s`-j8P%5)J>K;e?PGxr4c7!R5oJ#?ODPeb!3DjHvzmM z3$X_2ZX+782C0LreTg&TxuQ0(n~PYn$f6tahFuTVsztnVw;NJ2mV}ELDq=xQf-?ki zK06*`A$o9ehJ^tmsxb#zEatRS0 z2`D5H9mKpCo?k+Kcl_-C0#=-ZLTpa|Q9hFkc#-s9P~aCC(0V&nwJH`T`9R``UA$F{`RvEqzDPT029UlHQ?J;t@%-gc1Z0gMSfjJXpRSswHv&*S1385yGQ z?tSAPdFD5;UK!K;sjR9+4zfbk8^6gATZjCI6-*4`?Xq6CziK2;l<)e-Yyru8cej3@ zu})+?6Rg49%I;#06;tdrst@zw%(^1hgbyV=w2Le4naat{IetVmlfOJm`Qw7p!YZ6w z5a9?mi={PhWPP33qL3kj`o{S3Ja!~OGjltR~~E z9ZCr&1)&ZmHI~HSQaprSyT+Oj>rK`q^d}ViG@C-ejH^nbSI3-${XI>jykxO7wa;}F zT?=Wlr0TJdEhP{o(73}sF({5T=WqNf!Sf7;8HhS*E?d6oRy+_gh?&HV+KS`|R&2)_ zKmLb+*Cz2!KXp`QMhAYb0Z~3digE&MMm7l*Nlh1Z5Gu(EqWs^HL;{KC455ov4R;9y zzH8@9Pu6mTW4~lzeJ$;w-%;=9E`+{L6$SVq5oeolzd(9c!j;n6US=wG_jr!f-0n*5 z?m>mk0;=BH>pCI|5F%GD^mA?O+@0K=D59-#V&C7;7XEk8t2!(sGAUFi1Sb@Bi0Tdz z9LY>e$IqcwINO76(x_{)6a7K~i40YSAJ>>&NkFY1JLJ)?TkS2)h(}T4j5&+tk`ia` z{|2roKLau#Px&Ja2RVdg5+M?zF31z{QPV|y^pqs54v;5EvyM5Q3+emWqeyi2jyW17 zXl69}Gcz+aPDw#&(^`xcXYEt-s~Z1*g!3Ug zSdp~x0i5UP*P?~$PW_05V86v0NnmO=%n+#VqIcb!<}ugh7YZ{Ocv$6)F!|?14e1A{ z!Ea<%0PK3jf|a*aT>*+*pl1BoJm9D1=>S@{f!}78zkfmQXBx|1JQSfVs?BCJXg8ZW zsNKigRKh~BpeduMegQ)iKVre79XRfcw$ug&{sE5!gFr}&{we>2?|aMMg7=K~q<2YX zfOqb3hs!96h4uhpPYG+J`bSKDe7hZMU9B9>qn^^B7E?N4QyAzRYvT4_K@Co`I1kzx w7uSv^yS(zK(-z(po&S2#!ZgWAIVX^&MRHdDZ0`%6>(#ufcVc;U`NXpKKg*Y2djJ3c diff --git a/env/lib/python3.8/site-packages/click/__pycache__/termui.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/termui.cpython-38.pyc deleted file mode 100644 index 2623fc5c4a5450c9c3c21512eded52dcee680a45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21665 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 Q)2rBe6|?q4X|>k)KWNl`IRF3v diff --git a/env/lib/python3.8/site-packages/click/__pycache__/types.cpython-38.pyc b/env/lib/python3.8/site-packages/click/__pycache__/types.cpython-38.pyc deleted file mode 100644 index 0b4cd15b0cc877ae5db502781f90bb3bffc5c255..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22307 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 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 [] - - has_double_dash = "--" in all_args - - # 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 not has_double_dash and 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, use '_' to indicate no description - # is present. - echo(item[1] if item[1] else "_") - - return True - - -def do_complete_fish(cli, prog_name): - cwords = split_arg_string(os.environ["COMP_WORDS"]) - incomplete = os.environ["COMP_CWORD"] - args = cwords[1:] - - for item in get_choices(cli, prog_name, args, incomplete): - if item[1]: - echo("{arg}\t{desc}".format(arg=item[0], desc=item[1])) - else: - echo(item[0]) - - return True - - -def bashcomplete(cli, prog_name, complete_var, complete_instr): - if "_" in complete_instr: - command, shell = complete_instr.split("_", 1) - else: - command = complete_instr - shell = "bash" - - if command == "source": - echo(get_completion_script(prog_name, complete_var, shell)) - return True - elif command == "complete": - if shell == "fish": - return do_complete_fish(cli, prog_name) - elif shell in {"bash", "zsh"}: - return do_complete(cli, prog_name, shell == "zsh") - - return False diff --git a/env/lib/python3.8/site-packages/click/_compat.py b/env/lib/python3.8/site-packages/click/_compat.py deleted file mode 100644 index 60cb115b..00000000 --- a/env/lib/python3.8/site-packages/click/_compat.py +++ /dev/null @@ -1,786 +0,0 @@ -# flake8: noqa -import codecs -import io -import os -import re -import sys -from weakref import WeakKeyDictionary - -PY2 = sys.version_info[0] == 2 -CYGWIN = sys.platform.startswith("cygwin") -MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version) -# Determine local App Engine environment, per Google's own suggestion -APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get( - "SERVER_SOFTWARE", "" -) -WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2 -DEFAULT_COLUMNS = 80 - - -_ansi_re = re.compile(r"\033\[[;?0-9]*[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 - 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_compat_stream_attr(stream, attr, value): - """A stream attribute is compatible if it is equal to the - desired value or the desired value is unset and the attribute - has a value. - """ - stream_value = getattr(stream, attr, None) - return stream_value == value or (value is None and stream_value is not None) - - def _is_compatible_text_stream(stream, encoding, errors): - """Check if a stream's encoding and errors attributes are - compatible with the desired values. - """ - return _is_compat_stream_attr( - stream, "encoding", encoding - ) and _is_compat_stream_attr(stream, "errors", errors) - - def _force_correct_text_stream( - text_stream, - encoding, - errors, - is_binary, - find_binary, - force_readable=False, - force_writable=False, - ): - if is_binary(text_stream, False): - binary_reader = text_stream - else: - # If the stream looks compatible, and won't default to a - # misconfigured ascii encoding, return it as-is. - if _is_compatible_text_stream(text_stream, encoding, errors) and not ( - encoding is None and _stream_is_misconfigured(text_stream) - ): - return text_stream - - # Otherwise, get the underlying binary reader. - binary_reader = find_binary(text_stream) - - # If that's not possible, silently use the original reader - # and get mojibake instead of exceptions. - if binary_reader is None: - return text_stream - - # Default errors to replace instead of strict in order to get - # something that works. - if errors is None: - errors = "replace" - - # Wrap the binary stream in a text stream with the correct - # encoding parameters. - return _make_text_stream( - binary_reader, - encoding, - errors, - force_readable=force_readable, - force_writable=force_writable, - ) - - def _force_correct_text_reader(text_reader, encoding, errors, force_readable=False): - return _force_correct_text_stream( - text_reader, - encoding, - errors, - _is_binary_reader, - _find_binary_reader, - force_readable=force_readable, - ) - - def _force_correct_text_writer(text_writer, encoding, errors, force_writable=False): - return _force_correct_text_stream( - text_writer, - encoding, - errors, - _is_binary_writer, - _find_binary_writer, - 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 _wrap_io_open(file, mode, encoding, errors): - """On Python 2, :func:`io.open` returns a text file wrapper that - requires passing ``unicode`` to ``write``. Need to open the file in - binary mode then wrap it in a subclass that can write ``str`` and - ``unicode``. - - Also handles not passing ``encoding`` and ``errors`` in binary mode. - """ - binary = "b" in mode - - if binary: - kwargs = {} - else: - kwargs = {"encoding": encoding, "errors": errors} - - if not PY2 or binary: - return io.open(file, mode, **kwargs) - - f = io.open(file, "{}b".format(mode.replace("t", ""))) - return _make_text_stream(f, **kwargs) - - -def open_stream(filename, mode="r", encoding=None, errors="strict", atomic=False): - binary = "b" in mode - - # 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 binary: - return get_binary_stdout(), False - return get_text_stdout(encoding=encoding, errors=errors), False - if binary: - 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: - return _wrap_io_open(filename, mode, encoding, 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 errno - import random - - try: - perm = os.stat(filename).st_mode - except OSError: - perm = None - - flags = os.O_RDWR | os.O_CREAT | os.O_EXCL - - if binary: - flags |= getattr(os, "O_BINARY", 0) - - while True: - tmp_filename = os.path.join( - os.path.dirname(filename), - ".__atomic-write{:08x}".format(random.randrange(1 << 32)), - ) - try: - fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) - break - except OSError as e: - if e.errno == errno.EEXIST or ( - os.name == "nt" - and e.errno == errno.EACCES - and os.path.isdir(e.filename) - and os.access(e.filename, os.W_OK) - ): - continue - raise - - if perm is not None: - os.chmod(tmp_filename, perm) # in case perm includes bits in umask - - f = _wrap_io_open(fd, mode, encoding, errors) - 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 _is_jupyter_kernel_output(stream): - if WIN: - # TODO: Couldn't test on Windows, should't try to support until - # someone tests the details wrt colorama. - return - - while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): - stream = stream._stream - - return stream.__class__.__module__.startswith("ipykernel.") - - -def should_strip_ansi(stream=None, color=None): - if color is None: - if stream is None: - stream = sys.stdin - return not isatty(stream) and not _is_jupyter_kernel_output(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/env/lib/python3.8/site-packages/click/_termui_impl.py b/env/lib/python3.8/site-packages/click/_termui_impl.py deleted file mode 100644 index 88bec377..00000000 --- a/env/lib/python3.8/site-packages/click/_termui_impl.py +++ /dev/null @@ -1,657 +0,0 @@ -# -*- coding: utf-8 -*- -""" -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. -""" -import contextlib -import math -import os -import sys -import time - -from ._compat import _default_text_stdout -from ._compat import CYGWIN -from ._compat import get_best_encoding -from ._compat import int_types -from ._compat import isatty -from ._compat import open_stream -from ._compat import range_type -from ._compat import strip_ansi -from ._compat import term_len -from ._compat import WIN -from .exceptions import ClickException -from .utils import echo - -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 __next__(self): - # Iteration is defined in terms of a generator function, - # returned by iter(self); use that to define next(). This works - # because `self.iter` is an iterable consumed by that generator, - # so it is re-entry safe. Calling `next(self.generator())` - # twice works and does "what you want". - return next(iter(self)) - - # Python 2 compat - next = __next__ - - 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: - return "{}d {:02}:{:02}:{:02}".format(t, hours, minutes, seconds) - else: - return "{:02}:{:02}:{:02}".format(hours, minutes, seconds) - return "" - - def format_pos(self): - pos = str(self.pos) - if self.length_known: - pos += "/{}".format(self.length) - return pos - - def format_pct(self): - return "{: 4}%".format(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): - """Return a generator which yields the items added to the bar - during construction, and updates the progress bar *after* the - yielded block returns. - """ - # WARNING: the iterator interface for `ProgressBar` relies on - # this and only works because this is a simple generator which - # doesn't create or manage additional state. If this function - # changes, the impact should be evaluated both against - # `iter(bar)` and `next(bar)`. `next()` in particular may call - # `self.generator()` repeatedly, and this must remain safe in - # order for that interface to work. - 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 "{}"'.format(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 = "{}{}".format(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('{} "{}"'.format(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 "sensible-editor", "vim", "nano": - if os.system("which {} >/dev/null 2>&1".format(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( - '{} "{}"'.format(editor, filename), env=environ, shell=True, - ) - exit_code = c.wait() - if exit_code != 0: - raise ClickException("{}: Editing failed!".format(editor)) - except OSError as e: - raise ClickException("{}: Editing failed: {}".format(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,"{}"'.format(_unquote_file(url.replace('"', ""))) - else: - args = 'start {} "" "{}"'.format( - "/WAIT" if wait else "", url.replace('"', "") - ) - return os.system(args) - elif CYGWIN: - if locate: - url = _unquote_file(url) - args = 'cygstart "{}"'.format(os.path.dirname(url).replace('"', "")) - else: - args = 'cygstart {} "{}"'.format("-w" if wait else "", 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/env/lib/python3.8/site-packages/click/_textwrap.py b/env/lib/python3.8/site-packages/click/_textwrap.py deleted file mode 100644 index 6959087b..00000000 --- a/env/lib/python3.8/site-packages/click/_textwrap.py +++ /dev/null @@ -1,37 +0,0 @@ -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/env/lib/python3.8/site-packages/click/_unicodefun.py b/env/lib/python3.8/site-packages/click/_unicodefun.py deleted file mode 100644 index 781c3652..00000000 --- a/env/lib/python3.8/site-packages/click/_unicodefun.py +++ /dev/null @@ -1,131 +0,0 @@ -import codecs -import os -import sys - -from ._compat import PY2 - - -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 - - from . import disable_unicode_literals_warning - - if not PY2 or 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 locales were discovered. This most likely" - " requires resolving by reconfiguring the locale" - " system." - ) - elif has_c_utf8: - extra += ( - "This system supports the C.UTF-8 locale which is" - " recommended. You might be able to resolve your issue" - " by exporting the 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 you can pick from. The following suitable" - " locales were discovered: {}".format(", ".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" - " but the locale system could not pick up from it" - " because it does not exist. The exported locale is" - " '{}' but it is not supported".format(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/python3/ for" - " mitigation steps.{}".format(extra) - ) diff --git a/env/lib/python3.8/site-packages/click/_winconsole.py b/env/lib/python3.8/site-packages/click/_winconsole.py deleted file mode 100644 index b6c4274a..00000000 --- a/env/lib/python3.8/site-packages/click/_winconsole.py +++ /dev/null @@ -1,370 +0,0 @@ -# -*- 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 ctypes -import io -import os -import sys -import time -import zlib -from ctypes import byref -from ctypes import c_char -from ctypes import c_char_p -from ctypes import c_int -from ctypes import c_ssize_t -from ctypes import c_ulong -from ctypes import c_void_p -from ctypes import POINTER -from ctypes import py_object -from ctypes import windll -from ctypes import WinError -from ctypes import WINFUNCTYPE -from ctypes.wintypes import DWORD -from ctypes.wintypes import HANDLE -from ctypes.wintypes import LPCWSTR -from ctypes.wintypes import LPWSTR - -import msvcrt - -from ._compat import _NonClosingTextIOWrapper -from ._compat import PY2 -from ._compat import text_type - -try: - from ctypes import pythonapi - - PyObject_GetBuffer = pythonapi.PyObject_GetBuffer - PyBuffer_Release = pythonapi.PyBuffer_Release -except ImportError: - pythonapi = None - - -c_ssize_p = POINTER(c_ssize_t) - -kernel32 = windll.kernel32 -GetStdHandle = kernel32.GetStdHandle -ReadConsoleW = kernel32.ReadConsoleW -WriteConsoleW = kernel32.WriteConsoleW -GetConsoleMode = kernel32.GetConsoleMode -GetLastError = kernel32.GetLastError -GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) -CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( - ("CommandLineToArgvW", windll.shell32) -) -LocalFree = WINFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)( - ("LocalFree", windll.kernel32) -) - - -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( - HANDLE(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: {}".format(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 {}".format(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( - HANDLE(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 "".format( - 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)) - if not argv_unicode: - raise WinError() - try: - argv = [argv_unicode[i] for i in range(0, argc.value)] - finally: - LocalFree(argv_unicode) - del argv_unicode - - 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 _is_console(f): - if not hasattr(f, "fileno"): - return False - - try: - fileno = f.fileno() - except OSError: - return False - - handle = msvcrt.get_osfhandle(fileno) - return bool(GetConsoleMode(handle, byref(DWORD()))) - - -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 _is_console(f) - ): - 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/env/lib/python3.8/site-packages/click/core.py b/env/lib/python3.8/site-packages/click/core.py deleted file mode 100644 index f58bf26d..00000000 --- a/env/lib/python3.8/site-packages/click/core.py +++ /dev/null @@ -1,2030 +0,0 @@ -import errno -import inspect -import os -import sys -from contextlib import contextmanager -from functools import update_wrapper -from itertools import repeat - -from ._compat import isidentifier -from ._compat import iteritems -from ._compat import PY2 -from ._compat import string_types -from ._unicodefun import _check_for_unicode_literals -from ._unicodefun import _verify_python3_env -from .exceptions import Abort -from .exceptions import BadParameter -from .exceptions import ClickException -from .exceptions import Exit -from .exceptions import MissingParameter -from .exceptions import UsageError -from .formatting import HelpFormatter -from .formatting import join_options -from .globals import pop_context -from .globals import push_context -from .parser import OptionParser -from .parser import split_opt -from .termui import confirm -from .termui import prompt -from .termui import style -from .types import BOOL -from .types import convert_type -from .types import IntRange -from .utils import echo -from .utils import get_os_args -from .utils import make_default_short_help -from .utils import make_str -from .utils import PacifyFlushWrapper - -_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 = "_{}_COMPLETE".format(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( - "{}. Command '{}' is set to chain and '{}' was added as" - " subcommand but it in itself is a multi command. ('{}' is a {}" - " within a chained {} named '{}').".format( - 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: - from warnings import warn - - warn( - "Parameter callbacks take 3 args, (ctx, param, value). The" - " 2-arg style is deprecated and will be removed in 8.0.".format(callback), - DeprecationWarning, - 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.""" - 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. - - .. versionadded:: 7.1 - Added the `show_default` parameter. - - :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. - :param show_default: if True, shows defaults for all options. - Even if an option is later created with show_default=False, - this command-level setting overrides it. - """ - - 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, - show_default=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 = "{}_{}".format( - parent.auto_envvar_prefix, self.info_name.upper() - ) - else: - auto_envvar_prefix = auto_envvar_prefix.upper() - if auto_envvar_prefix is not None: - auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") - 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.show_default = show_default - - 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 = f'{__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 = "{} {}".format(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): # noqa: B902 - """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): # noqa: B902 - """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 __repr__(self): - return "<{} {}>".format(self.__class__.__name__, self.name) - - 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[0] if sys.argv else __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. - .. versionchanged:: 7.1 - Added the `no_args_is_help` 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 no_args_is_help: this controls what happens if no arguments are - provided. This option is disabled by default. - If enabled this will add ``--help`` as argument - if no arguments are passed - :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, - no_args_is_help=False, - 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.no_args_is_help = no_args_is_help - self.hidden = hidden - self.deprecated = deprecated - - def get_usage(self, ctx): - """Formats the usage line into a string and returns it. - - Calls :meth:`format_usage` internally. - """ - 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. - - This is a low-level method called by :meth:`get_usage`. - """ - 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. - - Calls :meth:`format_help` internally. - """ - 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 is a low-level method called by :meth:`get_help`. - - This calls 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): - if not args and self.no_args_is_help and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - 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{} ({})".format( - "s" if len(args) != 1 else "", " ".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 = "*" if args else 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 '{}'.".format(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`. - """ - from .decorators import 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`. - """ - from .decorators import group - - 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. - - :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. - :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. - - .. versionchanged:: 7.1 - Empty environment variables are ignored rather than taking the - empty string value. This makes it possible for scripts to clear - variables if they can't unset them. - - .. versionchanged:: 2.0 - Changed signature for parameter callback to also be passed the - parameter. The old callback format will still work, but it will - raise a warning to give you a chance to migrate the code easier. - """ - 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 - - def __repr__(self): - return "<{} {}>".format(self.__class__.__name__, self.name) - - @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 {}. This is not supported; nargs" - " needs to be set to a fixed value > 1.".format(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: - rv = os.environ.get(self.envvar) - - if rv != "": - return rv - - 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(repr(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 in [None, bool]: - 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 = ";" if decl[:1] == "/" else "/" - 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 ({}). Did you" - " mean to declare an argument instead of an option?".format(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) - action_const = "{}_const".format(action) - 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 += " {}".format(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 = "{}_{}".format(ctx.auto_envvar_prefix, self.name.upper()) - if envvar is not None: - extra.append( - "env var: {}".format( - ", ".join(str(d) for d in envvar) - if isinstance(envvar, (list, tuple)) - else envvar - ) - ) - if self.default is not None and (self.show_default or ctx.show_default): - if isinstance(self.show_default, string_types): - default_string = "({})".format(self.show_default) - elif isinstance(self.default, (list, tuple)): - default_string = ", ".join(str(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 = "{}[{}]".format( - "{} ".format(help) if help else "", "; ".join(extra) - ) - - return ("; " if any_prefix_is_slash else " / ").join(rv), help - - def get_default(self, ctx): - # If we're a non boolean flag our 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 = "{}_{}".format(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 = "[{}]".format(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" - " {}".format(len(decls)) - ) - return name, [arg], [] - - def get_usage_pieces(self, ctx): - return [self.make_metavar()] - - def get_error_hint(self, ctx): - return repr(self.make_metavar()) - - def add_to_parser(self, parser, ctx): - parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/env/lib/python3.8/site-packages/click/decorators.py b/env/lib/python3.8/site-packages/click/decorators.py deleted file mode 100644 index c7b5af6c..00000000 --- a/env/lib/python3.8/site-packages/click/decorators.py +++ /dev/null @@ -1,333 +0,0 @@ -import inspect -import sys -from functools import update_wrapper - -from ._compat import iteritems -from ._unicodefun import _check_for_unicode_literals -from .core import Argument -from .core import Command -from .core import Group -from .core import Option -from .globals import get_current_context -from .utils import echo - - -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 '{}' existing".format(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 with - underscores replaced by dashes. 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 _, 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 diff --git a/env/lib/python3.8/site-packages/click/exceptions.py b/env/lib/python3.8/site-packages/click/exceptions.py deleted file mode 100644 index 592ee38f..00000000 --- a/env/lib/python3.8/site-packages/click/exceptions.py +++ /dev/null @@ -1,253 +0,0 @@ -from ._compat import filename_to_ui -from ._compat import get_text_stderr -from ._compat import PY2 -from .utils import echo - - -def _join_param_hints(param_hint): - if isinstance(param_hint, (tuple, list)): - return " / ".join(repr(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: {}".format(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.command if self.ctx else 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 '{} {}' for help.\n".format( - self.ctx.command_path, self.ctx.help_option_names[0] - ) - if self.ctx is not None: - color = self.ctx.color - echo("{}\n{}".format(self.ctx.get_usage(), hint), file=file, color=color) - echo("Error: {}".format(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: {}".format(self.message) - param_hint = _join_param_hints(param_hint) - - return "Invalid value for {}: {}".format(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 += ". {}".format(msg_extra) - else: - msg = msg_extra - - return "Missing {}{}{}{}".format( - param_type, - " {}".format(param_hint) if param_hint else "", - ". " if msg else ".", - msg or "", - ) - - def __str__(self): - if self.message is None: - param_name = self.param.name if self.param else None - return "missing parameter: {}".format(param_name) - else: - return self.message - - if PY2: - __unicode__ = __str__ - - def __str__(self): - return self.__unicode__().encode("utf-8") - - -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: {}".format(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 {}?".format(self.possibilities[0])) - else: - possibilities = sorted(self.possibilities) - bits.append("(Possible options: {})".format(", ".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 {}: {}".format(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. - """ - - __slots__ = ("exit_code",) - - def __init__(self, code=0): - self.exit_code = code diff --git a/env/lib/python3.8/site-packages/click/formatting.py b/env/lib/python3.8/site-packages/click/formatting.py deleted file mode 100644 index 319c7f61..00000000 --- a/env/lib/python3.8/site-packages/click/formatting.py +++ /dev/null @@ -1,283 +0,0 @@ -from contextlib import contextmanager - -from ._compat import term_len -from .parser import split_opt -from .termui import get_terminal_size - -# 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 = "{:>{w}}{} ".format(prefix, prog, w=self.current_indent) - 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("{:>{w}}{}:\n".format("", heading, w=self.current_indent)) - - 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("{:>{w}}{}".format("", first, w=self.current_indent)) - 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) - wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) - lines = wrapped_text.splitlines() - - if lines: - self.write("{}\n".format(lines[0])) - - for line in lines[1:]: - self.write( - "{:>{w}}{}\n".format( - "", line, w=first_col + self.current_indent - ) - ) - - if len(lines) > 1: - # separate long help from next option - self.write("\n") - 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/env/lib/python3.8/site-packages/click/globals.py b/env/lib/python3.8/site-packages/click/globals.py deleted file mode 100644 index 1649f9a0..00000000 --- a/env/lib/python3.8/site-packages/click/globals.py +++ /dev/null @@ -1,47 +0,0 @@ -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: if set to `True` the return value is `None` if no context - is available. The default behavior is to raise a - :exc:`RuntimeError`. - """ - try: - return _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/env/lib/python3.8/site-packages/click/parser.py b/env/lib/python3.8/site-packages/click/parser.py deleted file mode 100644 index f43ebfe9..00000000 --- a/env/lib/python3.8/site-packages/click/parser.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -""" -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. - -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. -""" -import re -from collections import deque - -from .exceptions import BadArgumentUsage -from .exceptions import BadOptionUsage -from .exceptions import NoSuchOption -from .exceptions import UsageError - - -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, "{} option requires an argument".format(opt)) - raise BadOptionUsage(opt, "{} option requires {} arguments".format(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"('([^'\\]*(?:\\.[^'\\]*)*)'|\"([^\"\\]*(?:\\.[^\"\\]*)*)\"|\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 ({})".format(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 '{}'".format(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 {} takes {} values".format(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 = {"-", "--"} - 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, "{} option does not take a value".format(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("{}{}".format(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/env/lib/python3.8/site-packages/click/termui.py b/env/lib/python3.8/site-packages/click/termui.py deleted file mode 100644 index 02ef9e9f..00000000 --- a/env/lib/python3.8/site-packages/click/termui.py +++ /dev/null @@ -1,681 +0,0 @@ -import inspect -import io -import itertools -import os -import struct -import sys - -from ._compat import DEFAULT_COLUMNS -from ._compat import get_winterm_size -from ._compat import isatty -from ._compat import raw_input -from ._compat import string_types -from ._compat import strip_ansi -from ._compat import text_type -from ._compat import WIN -from .exceptions import Abort -from .exceptions import UsageError -from .globals import resolve_color_default -from .types import Choice -from .types import convert_type -from .types import Path -from .utils import echo -from .utils import LazyFile - -# 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 += " ({})".format(", ".join(map(str, type.choices))) - if default is not None and show_default: - prompt = "{} [{}]".format(prompt, _format_default(default)) - return prompt + suffix - - -def _format_default(default): - if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): - return default.name - - return default - - -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 = hidden_prompt_func if hide_input else 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: {}".format(e.message), err=err) # noqa: B306 - 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, "Y/n" if default else "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 created. 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. - - Note: The progress bar is currently designed for use cases where the - total progress can be expected to take at least several seconds. - Because of this, the ProgressBar class object won't display - progress that is considered too fast, and progress where the time - between steps is less than a second. - - 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[{}m".format(_ansi_colors[fg])) - except KeyError: - raise TypeError("Unknown color '{}'".format(fg)) - if bg: - try: - bits.append("\033[{}m".format(_ansi_colors[bg] + 10)) - except KeyError: - raise TypeError("Unknown color '{}'".format(bg)) - if bold is not None: - bits.append("\033[{}m".format(1 if bold else 22)) - if dim is not None: - bits.append("\033[{}m".format(2 if dim else 22)) - if underline is not None: - bits.append("\033[{}m".format(4 if underline else 24)) - if blink is not None: - bits.append("\033[{}m".format(5 if blink else 25)) - if reverse is not None: - bits.append("\033[{}m".format(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/env/lib/python3.8/site-packages/click/testing.py b/env/lib/python3.8/site-packages/click/testing.py deleted file mode 100644 index a3dba3b3..00000000 --- a/env/lib/python3.8/site-packages/click/testing.py +++ /dev/null @@ -1,382 +0,0 @@ -import contextlib -import os -import shlex -import shutil -import sys -import tempfile - -from . import formatting -from . import termui -from . import utils -from ._compat import iteritems -from ._compat import PY2 -from ._compat import string_types - - -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 None 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 self.stderr_bytes is None: - raise ValueError("stderr not separately captured") - return self.stderr_bytes.decode(self.runner.charset, "replace").replace( - "\r\n", "\n" - ) - - def __repr__(self): - return "<{} {}>".format( - type(self).__name__, repr(self.exception) if self.exception else "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 = formatting.FORCED_WIDTH - 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("{}\n".format(val)) - sys.stdout.flush() - return val - - def hidden_input(prompt=None): - sys.stdout.write("{}\n".format(prompt or "")) - 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 = termui.visible_prompt_func - old_hidden_prompt_func = termui.hidden_prompt_func - old__getchar_func = termui._getchar - old_should_strip_ansi = utils.should_strip_ansi - termui.visible_prompt_func = visible_input - termui.hidden_prompt_func = hidden_input - termui._getchar = _getchar - 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 - termui.visible_prompt_func = old_visible_prompt_func - termui.hidden_prompt_func = old_hidden_prompt_func - termui._getchar = old__getchar_func - utils.should_strip_ansi = old_should_strip_ansi - formatting.FORCED_WIDTH = old_forced_width - - def invoke( - self, - cli, - args=None, - input=None, - env=None, - catch_exceptions=True, - color=False, - **extra - ): - """Invokes a command in an isolated environment. The arguments are - forwarded directly to the command line script, the `extra` keyword - arguments are passed to the :meth:`~clickpkg.Command.main` function of - the command. - - This returns a :class:`Result` object. - - .. versionadded:: 3.0 - The ``catch_exceptions`` parameter was added. - - .. versionchanged:: 3.0 - The result object now has an `exc_info` attribute with the - traceback if available. - - .. versionadded:: 4.0 - The ``color`` parameter was added. - - :param cli: the command to invoke - :param args: the arguments to invoke. 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() - if self.mix_stderr: - stderr = None - else: - stderr = 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): # noqa: B014 - pass diff --git a/env/lib/python3.8/site-packages/click/types.py b/env/lib/python3.8/site-packages/click/types.py deleted file mode 100644 index 505c39f8..00000000 --- a/env/lib/python3.8/site-packages/click/types.py +++ /dev/null @@ -1,762 +0,0 @@ -import os -import stat -from datetime import datetime - -from ._compat import _get_argv_encoding -from ._compat import filename_to_ui -from ._compat import get_filesystem_encoding -from ._compat import get_streerror -from ._compat import open_stream -from ._compat import PY2 -from ._compat import text_type -from .exceptions import BadParameter -from .utils import LazyFile -from .utils import safecall - - -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") - else: - 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. - - The resulting value will always be one of the originally passed choices - regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` - being specified. - - 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 "[{}]".format("|".join(self.choices)) - - def get_missing_message(self, param): - return "Choose from:\n\t{}.".format(",\n\t".join(self.choices)) - - def convert(self, value, param, ctx): - # 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 = {choice: choice for choice in 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(normed_choice): original - for normed_choice, original in normed_choices.items() - } - - if not self.case_sensitive: - if PY2: - lower = str.lower - else: - lower = str.casefold - - normed_value = lower(normed_value) - normed_choices = { - lower(normed_choice): original - for normed_choice, original in normed_choices.items() - } - - if normed_value in normed_choices: - return normed_choices[normed_value] - - self.fail( - "invalid choice: {}. (choose from {})".format( - value, ", ".join(self.choices) - ), - param, - ctx, - ) - - def __repr__(self): - return "Choice('{}')".format(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: - self.fail("{} is not a valid integer".format(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( - "{} is bigger than the maximum valid value {}.".format( - rv, self.max - ), - param, - ctx, - ) - elif self.max is None: - self.fail( - "{} is smaller than the minimum valid value {}.".format( - rv, self.min - ), - param, - ctx, - ) - else: - self.fail( - "{} is not in the valid range of {} to {}.".format( - rv, self.min, self.max - ), - param, - ctx, - ) - return rv - - def __repr__(self): - return "IntRange({}, {})".format(self.min, self.max) - - -class FloatParamType(ParamType): - name = "float" - - def convert(self, value, param, ctx): - try: - return float(value) - except ValueError: - self.fail( - "{} is not a valid floating point value".format(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( - "{} is bigger than the maximum valid value {}.".format( - rv, self.max - ), - param, - ctx, - ) - elif self.max is None: - self.fail( - "{} is smaller than the minimum valid value {}.".format( - rv, self.min - ), - param, - ctx, - ) - else: - self.fail( - "{} is not in the valid range of {} to {}.".format( - rv, self.min, self.max - ), - param, - ctx, - ) - return rv - - def __repr__(self): - return "FloatRange({}, {})".format(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("{} is not a valid boolean".format(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 ValueError: - self.fail("{} is not a valid UUID value".format(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: # noqa: B014 - self.fail( - "Could not open file: {}: {}".format( - 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( - "{} '{}' does not exist.".format( - self.path_type, filename_to_ui(value) - ), - param, - ctx, - ) - - if not self.file_okay and stat.S_ISREG(st.st_mode): - self.fail( - "{} '{}' is a file.".format(self.path_type, filename_to_ui(value)), - param, - ctx, - ) - if not self.dir_okay and stat.S_ISDIR(st.st_mode): - self.fail( - "{} '{}' is a directory.".format( - self.path_type, filename_to_ui(value) - ), - param, - ctx, - ) - if self.writable and not os.access(value, os.W_OK): - self.fail( - "{} '{}' is not writable.".format( - self.path_type, filename_to_ui(value) - ), - param, - ctx, - ) - if self.readable and not os.access(value, os.R_OK): - self.fail( - "{} '{}' is not readable.".format( - 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 "<{}>".format(" ".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 type into the most appropriate - param type. - """ - 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 ({}).".format(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/env/lib/python3.8/site-packages/click/utils.py b/env/lib/python3.8/site-packages/click/utils.py deleted file mode 100644 index 79265e73..00000000 --- a/env/lib/python3.8/site-packages/click/utils.py +++ /dev/null @@ -1,455 +0,0 @@ -import os -import sys - -from ._compat import _default_text_stderr -from ._compat import _default_text_stdout -from ._compat import auto_wrap_for_ansi -from ._compat import binary_streams -from ._compat import filename_to_ui -from ._compat import get_filesystem_encoding -from ._compat import get_streerror -from ._compat import is_bytes -from ._compat import open_stream -from ._compat import PY2 -from ._compat import should_strip_ansi -from ._compat import string_types -from ._compat import strip_ansi -from ._compat import text_streams -from ._compat import text_type -from ._compat import WIN -from .globals import resolve_color_default - -if not PY2: - from ._compat import _find_binary_writer -elif WIN: - from ._winconsole import _get_windows_argv - from ._winconsole import _hash_py_argv - from ._winconsole import _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 = 1 + len(word) if result else 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 "".format(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: # noqa: E402 - 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 '{}'".format(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 '{}'".format(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 = "APPDATA" if roaming else "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("~/.{}".format(_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/env/lib/python3.8/site-packages/easy_install.py b/env/lib/python3.8/site-packages/easy_install.py deleted file mode 100644 index d87e9840..00000000 --- a/env/lib/python3.8/site-packages/easy_install.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Run the EasyInstall command""" - -if __name__ == '__main__': - from setuptools.command.easy_install import main - main() diff --git a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/INSTALLER b/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/LICENSE b/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/LICENSE deleted file mode 100644 index 3e92463e..00000000 --- a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 Sebastián Ramírez - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/METADATA b/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/METADATA deleted file mode 100644 index 89991b43..00000000 --- a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/METADATA +++ /dev/null @@ -1,545 +0,0 @@ -Metadata-Version: 2.1 -Name: fastapi -Version: 0.61.2 -Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production -Home-page: https://github.com/tiangolo/fastapi -License: UNKNOWN -Author: Sebastián Ramírez -Author-email: tiangolo@gmail.com -Requires-Python: >=3.6 -Description-Content-Type: text/markdown -Classifier: Intended Audience :: Information Technology -Classifier: Intended Audience :: System Administrators -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python -Classifier: Topic :: Internet -Classifier: Topic :: Software Development :: Libraries :: Application Frameworks -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Software Development :: Libraries -Classifier: Topic :: Software Development -Classifier: Typing :: Typed -Classifier: Development Status :: 4 - Beta -Classifier: Environment :: Web Environment -Classifier: Framework :: AsyncIO -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers -Classifier: Topic :: Internet :: WWW/HTTP -Requires-Dist: starlette ==0.13.6 -Requires-Dist: pydantic >=1.0.0,<2.0.0 -Requires-Dist: requests >=2.24.0,<3.0.0 ; extra == "all" -Requires-Dist: aiofiles >=0.5.0,<0.6.0 ; extra == "all" -Requires-Dist: jinja2 >=2.11.2,<3.0.0 ; extra == "all" -Requires-Dist: python-multipart >=0.0.5,<0.0.6 ; extra == "all" -Requires-Dist: itsdangerous >=1.1.0,<2.0.0 ; extra == "all" -Requires-Dist: pyyaml >=5.3.1,<6.0.0 ; extra == "all" -Requires-Dist: graphene >=2.1.8,<3.0.0 ; extra == "all" -Requires-Dist: ujson >=3.0.0,<4.0.0 ; extra == "all" -Requires-Dist: orjson >=3.2.1,<4.0.0 ; extra == "all" -Requires-Dist: email_validator >=1.1.1,<2.0.0 ; extra == "all" -Requires-Dist: uvicorn >=0.11.5,<0.12.0 ; extra == "all" -Requires-Dist: async_exit_stack >=1.0.1,<2.0.0 ; extra == "all" -Requires-Dist: async_generator >=1.10,<2.0.0 ; extra == "all" -Requires-Dist: python-jose[cryptography] >=3.1.0,<4.0.0 ; extra == "dev" -Requires-Dist: passlib[bcrypt] >=1.7.2,<2.0.0 ; extra == "dev" -Requires-Dist: autoflake >=1.3.1,<2.0.0 ; extra == "dev" -Requires-Dist: flake8 >=3.8.3,<4.0.0 ; extra == "dev" -Requires-Dist: uvicorn >=0.11.5,<0.12.0 ; extra == "dev" -Requires-Dist: graphene >=2.1.8,<3.0.0 ; extra == "dev" -Requires-Dist: mkdocs >=1.1.2,<2.0.0 ; extra == "doc" -Requires-Dist: mkdocs-material >=5.5.0,<6.0.0 ; extra == "doc" -Requires-Dist: markdown-include >=0.5.1,<0.6.0 ; extra == "doc" -Requires-Dist: mkdocs-markdownextradata-plugin >=0.1.7,<0.2.0 ; extra == "doc" -Requires-Dist: typer >=0.3.0,<0.4.0 ; extra == "doc" -Requires-Dist: typer-cli >=0.0.9,<0.0.10 ; extra == "doc" -Requires-Dist: pyyaml >=5.3.1,<6.0.0 ; extra == "doc" -Requires-Dist: pytest ==5.4.3 ; extra == "test" -Requires-Dist: pytest-cov ==2.10.0 ; extra == "test" -Requires-Dist: pytest-asyncio >=0.14.0,<0.15.0 ; extra == "test" -Requires-Dist: mypy ==0.782 ; extra == "test" -Requires-Dist: flake8 >=3.8.3,<4.0.0 ; extra == "test" -Requires-Dist: black ==19.10b0 ; extra == "test" -Requires-Dist: isort >=5.0.6,<6.0.0 ; extra == "test" -Requires-Dist: requests >=2.24.0,<3.0.0 ; extra == "test" -Requires-Dist: httpx >=0.14.0,<0.15.0 ; extra == "test" -Requires-Dist: email_validator >=1.1.1,<2.0.0 ; extra == "test" -Requires-Dist: sqlalchemy >=1.3.18,<2.0.0 ; extra == "test" -Requires-Dist: peewee >=3.13.3,<4.0.0 ; extra == "test" -Requires-Dist: databases[sqlite] >=0.3.2,<0.4.0 ; extra == "test" -Requires-Dist: orjson >=3.2.1,<4.0.0 ; extra == "test" -Requires-Dist: async_exit_stack >=1.0.1,<2.0.0 ; extra == "test" -Requires-Dist: async_generator >=1.10,<2.0.0 ; extra == "test" -Requires-Dist: python-multipart >=0.0.5,<0.0.6 ; extra == "test" -Requires-Dist: aiofiles >=0.5.0,<0.6.0 ; extra == "test" -Requires-Dist: flask >=1.1.2,<2.0.0 ; extra == "test" -Project-URL: Documentation, https://fastapi.tiangolo.com/ -Provides-Extra: all -Provides-Extra: dev -Provides-Extra: doc -Provides-Extra: test - -

    -

    - FastAPI framework, high performance, easy to learn, fast to code, ready for production -

    -

    - - Test - - - Coverage - - - Package version - - - Join the chat at https://gitter.im/tiangolo/fastapi - -

    - ---- - -**Documentation**: https://fastapi.tiangolo.com - -**Source Code**: https://github.com/tiangolo/fastapi - ---- - -FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. - -The key features are: - -* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). - -* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * -* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * -* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. -* **Easy**: Designed to be easy to use and learn. Less time reading docs. -* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. -* **Robust**: Get production-ready code. With automatic interactive documentation. -* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema. - -* estimation based on tests on an internal development team, building production applications. - -## Gold Sponsors - - - - - - - -Other sponsors - -## Opinions - -"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" - -
    Kabir Khan - Microsoft (ref)
    - ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -
    Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
    - ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -
    Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
    - ---- - -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" - -
    Brian Okken - Python Bytes podcast host (ref)
    - ---- - -"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._" - -
    Timothy Crosley - Hug creator (ref)
    - ---- - -"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_" - -"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" - -
    Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
    - ---- - -## **Typer**, the FastAPI of CLIs - - - -If you are building a CLI app to be used in the terminal instead of a web API, check out **Typer**. - -**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀 - -## Requirements - -Python 3.6+ - -FastAPI stands on the shoulders of giants: - -* Starlette for the web parts. -* Pydantic for the data parts. - -## Installation - -
    - -```console -$ pip install fastapi - ----> 100% -``` - -
    - -You will also need an ASGI server, for production such as Uvicorn or Hypercorn. - -
    - -```console -$ pip install uvicorn - ----> 100% -``` - -
    - -## Example - -### Create it - -* Create a file `main.py` with: - -```Python -from typing import Optional - -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: Optional[str] = None): - return {"item_id": item_id, "q": q} -``` - -
    -Or use async def... - -If your code uses `async` / `await`, use `async def`: - -```Python hl_lines="9 14" -from typing import Optional - -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -async def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -async def read_item(item_id: int, q: Optional[str] = None): - return {"item_id": item_id, "q": q} -``` - -**Note**: - -If you don't know, check the _"In a hurry?"_ section about `async` and `await` in the docs. - -
    - -### Run it - -Run the server with: - -
    - -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [28720] -INFO: Started server process [28722] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -
    - -
    -About the command uvicorn main:app --reload... - -The command `uvicorn main:app` refers to: - -* `main`: the file `main.py` (the Python "module"). -* `app`: the object created inside of `main.py` with the line `app = FastAPI()`. -* `--reload`: make the server restart after code changes. Only do this for development. - -
    - -### Check it - -Open your browser at http://127.0.0.1:8000/items/5?q=somequery. - -You will see the JSON response as: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -You already created an API that: - -* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`. -* Both _paths_ take `GET` operations (also known as HTTP _methods_). -* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`. -* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`. - -### Interactive API docs - -Now go to http://127.0.0.1:8000/docs. - -You will see the automatic interactive API documentation (provided by Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternative API docs - -And now, go to http://127.0.0.1:8000/redoc. - -You will see the alternative automatic documentation (provided by ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Example upgrade - -Now modify the file `main.py` to receive a body from a `PUT` request. - -Declare the body using standard Python types, thanks to Pydantic. - -```Python hl_lines="4 9-12 25-27" -from typing import Optional - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - is_offer: Optional[bool] = None - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: Optional[str] = None): - return {"item_id": item_id, "q": q} - - -@app.put("/items/{item_id}") -def update_item(item_id: int, item: Item): - return {"item_name": item.name, "item_id": item_id} -``` - -The server should reload automatically (because you added `--reload` to the `uvicorn` command above). - -### Interactive API docs upgrade - -Now go to http://127.0.0.1:8000/docs. - -* The interactive API documentation will be automatically updated, including the new body: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Alternative API docs upgrade - -And now, go to http://127.0.0.1:8000/redoc. - -* The alternative documentation will also reflect the new query parameter and body: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Recap - -In summary, you declare **once** the types of parameters, body, etc. as function parameters. - -You do that with standard modern Python types. - -You don't have to learn a new syntax, the methods or classes of a specific library, etc. - -Just standard **Python 3.6+**. - -For example, for an `int`: - -```Python -item_id: int -``` - -or for a more complex `Item` model: - -```Python -item: Item -``` - -...and with that single declaration you get: - -* Editor support, including: - * Completion. - * Type checks. -* Validation of data: - * Automatic and clear errors when the data is invalid. - * Validation even for deeply nested JSON objects. -* Conversion of input data: coming from the network to Python data and types. Reading from: - * JSON. - * Path parameters. - * Query parameters. - * Cookies. - * Headers. - * Forms. - * Files. -* Conversion of output data: converting from Python data and types to network data (as JSON): - * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). - * `datetime` objects. - * `UUID` objects. - * Database models. - * ...and many more. -* Automatic interactive API documentation, including 2 alternative user interfaces: - * Swagger UI. - * ReDoc. - ---- - -Coming back to the previous code example, **FastAPI** will: - -* Validate that there is an `item_id` in the path for `GET` and `PUT` requests. -* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests. - * If it is not, the client will see a useful, clear error. -* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests. - * As the `q` parameter is declared with `= None`, it is optional. - * Without the `None` it would be required (as is the body in the case with `PUT`). -* For `PUT` requests to `/items/{item_id}`, Read the body as JSON: - * Check that it has a required attribute `name` that should be a `str`. - * Check that it has a required attribute `price` that has to be a `float`. - * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. - * All this would also work for deeply nested JSON objects. -* Convert from and to JSON automatically. -* Document everything with OpenAPI, that can be used by: - * Interactive documentation systems. - * Automatic client code generation systems, for many languages. -* Provide 2 interactive documentation web interfaces directly. - ---- - -We just scratched the surface, but you already get the idea of how it all works. - -Try changing the line with: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...from: - -```Python - ... "item_name": item.name ... -``` - -...to: - -```Python - ... "item_price": item.price ... -``` - -...and see how your editor will auto-complete the attributes and know their types: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -For a more complete example including more features, see the Tutorial - User Guide. - -**Spoiler alert**: the tutorial - user guide includes: - -* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**. -* How to set **validation constraints** as `maximum_length` or `regex`. -* A very powerful and easy to use **Dependency Injection** system. -* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. -* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic). -* Many extra features (thanks to Starlette) as: - * **WebSockets** - * **GraphQL** - * extremely easy tests based on `requests` and `pytest` - * **CORS** - * **Cookie Sessions** - * ...and more. - -## Performance - -Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*) - -To understand more about it, see the section Benchmarks. - -## Optional Dependencies - -Used by Pydantic: - -* ujson - for faster JSON "parsing". -* email_validator - for email validation. - -Used by Starlette: - -* requests - Required if you want to use the `TestClient`. -* aiofiles - Required if you want to use `FileResponse` or `StaticFiles`. -* jinja2 - Required if you want to use the default template configuration. -* python-multipart - Required if you want to support form "parsing", with `request.form()`. -* itsdangerous - Required for `SessionMiddleware` support. -* pyyaml - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI). -* graphene - Required for `GraphQLApp` support. -* ujson - Required if you want to use `UJSONResponse`. - -Used by FastAPI / Starlette: - -* uvicorn - for the server that loads and serves your application. -* orjson - Required if you want to use `ORJSONResponse`. - -You can install all of these with `pip install fastapi[all]`. - -## License - -This project is licensed under the terms of the MIT license. - diff --git a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/RECORD b/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/RECORD deleted file mode 100644 index 5a3b6a95..00000000 --- a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/RECORD +++ /dev/null @@ -1,86 +0,0 @@ -fastapi-0.61.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -fastapi-0.61.2.dist-info/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086 -fastapi-0.61.2.dist-info/METADATA,sha256=qQZJ2dQ3wx1vcU7TXZ3sCN9tuQ9sGIK3PkD9MNf4p0E,23032 -fastapi-0.61.2.dist-info/RECORD,, -fastapi-0.61.2.dist-info/WHEEL,sha256=CqyTrkghQBNsEzLD3HbCSEIJ_fY58-XpoU29dUzwHSk,81 -fastapi/__init__.py,sha256=cFdnFn8xxyBcvagVFhuCW8YEjLYo2hd9eG-gnNvlrjg,582 -fastapi/__pycache__/__init__.cpython-38.pyc,, -fastapi/__pycache__/applications.cpython-38.pyc,, -fastapi/__pycache__/background.cpython-38.pyc,, -fastapi/__pycache__/concurrency.cpython-38.pyc,, -fastapi/__pycache__/datastructures.cpython-38.pyc,, -fastapi/__pycache__/encoders.cpython-38.pyc,, -fastapi/__pycache__/exception_handlers.cpython-38.pyc,, -fastapi/__pycache__/exceptions.cpython-38.pyc,, -fastapi/__pycache__/logger.cpython-38.pyc,, -fastapi/__pycache__/param_functions.cpython-38.pyc,, -fastapi/__pycache__/params.cpython-38.pyc,, -fastapi/__pycache__/requests.cpython-38.pyc,, -fastapi/__pycache__/responses.cpython-38.pyc,, -fastapi/__pycache__/routing.cpython-38.pyc,, -fastapi/__pycache__/staticfiles.cpython-38.pyc,, -fastapi/__pycache__/templating.cpython-38.pyc,, -fastapi/__pycache__/testclient.cpython-38.pyc,, -fastapi/__pycache__/utils.cpython-38.pyc,, -fastapi/__pycache__/websockets.cpython-38.pyc,, -fastapi/applications.py,sha256=-tj4l8oT1ICIaJKUArdhRhw86WcqRp8gw4jJAu8jvIU,30321 -fastapi/background.py,sha256=FSIsaZ_hEw5I3wP0UcgI_1hgAr6xdK6DpVX7_iKqlq8,57 -fastapi/concurrency.py,sha256=6iX8uR4POFbwZQEiDKV3BjaMlm_1BbMv2-fcalM_Z9k,1479 -fastapi/datastructures.py,sha256=TrtXz3hJi5_iuRjWDbsdyl87pL4sVZKOrsHET5zO9LY,499 -fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/dependencies/__pycache__/__init__.cpython-38.pyc,, -fastapi/dependencies/__pycache__/models.cpython-38.pyc,, -fastapi/dependencies/__pycache__/utils.cpython-38.pyc,, -fastapi/dependencies/models.py,sha256=zyHc4eH8CUTJCpO44Ymh0BQq0SdD5tJVmu843kiSivI,2479 -fastapi/dependencies/utils.py,sha256=dpqyegc1NTdk0UB8Ce9m4ZLtWA5Xzx2dVW8ErgZX7sM,28702 -fastapi/encoders.py,sha256=-hZFlvOIo5W8XP-HUxx4zxe-J7actLrm6JSUn995Y1s,5111 -fastapi/exception_handlers.py,sha256=UVYCCe4qt5-5_NuQ3SxTXjDvOdKMHiTfcLp3RUKXhg8,912 -fastapi/exceptions.py,sha256=KDnOOHp1EQ_Pz4XG9nHKYbf7AcagVwhsa6s72w6IRsQ,1080 -fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54 -fastapi/middleware/__init__.py,sha256=o0EmAqSU90no3OG3ss7l90vMOiWMofSEKzys6MMZTnA,44 -fastapi/middleware/__pycache__/__init__.cpython-38.pyc,, -fastapi/middleware/__pycache__/cors.cpython-38.pyc,, -fastapi/middleware/__pycache__/gzip.cpython-38.pyc,, -fastapi/middleware/__pycache__/httpsredirect.cpython-38.pyc,, -fastapi/middleware/__pycache__/trustedhost.cpython-38.pyc,, -fastapi/middleware/__pycache__/wsgi.cpython-38.pyc,, -fastapi/middleware/cors.py,sha256=JuDXB2k7otpUI6gGpxhlOiKjstRi93vz4ufPjqhSJhQ,61 -fastapi/middleware/gzip.py,sha256=RI-EIt2FaWnOMoR2z0UdVrroWddDW0zbqEgkprppbz8,61 -fastapi/middleware/httpsredirect.py,sha256=EWp-E7TZkUWNdvOlRsfNGzycqQuuAOvww9gAY7OodAM,79 -fastapi/middleware/trustedhost.py,sha256=JxqTvOgO1CMiVQSylBhmiwbIWASqDe2nbCyQJ5SWuq0,75 -fastapi/middleware/wsgi.py,sha256=UwCSA86LHYpFOd1Li4Xq015qtlIMvSJLct21Q3f4C3s,61 -fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/openapi/__pycache__/__init__.cpython-38.pyc,, -fastapi/openapi/__pycache__/constants.cpython-38.pyc,, -fastapi/openapi/__pycache__/docs.cpython-38.pyc,, -fastapi/openapi/__pycache__/models.cpython-38.pyc,, -fastapi/openapi/__pycache__/utils.cpython-38.pyc,, -fastapi/openapi/constants.py,sha256=sJSpZzRp7Kky9R-jucU-K6_pJzLBRO75ddW7-MixZWc,166 -fastapi/openapi/docs.py,sha256=Xnzr6Hs-kHZcQZAdgoC1xLwLtZL8gTmrAIMS89AvXrM,5517 -fastapi/openapi/models.py,sha256=5UA7ggkrlOV2F-k_H4H3S_p3xDI-FJUIABdK1IFLzcU,10413 -fastapi/openapi/utils.py,sha256=4ThsfYlcmKMo1qVYOWwQDzm5BISaoy1hkC-ucafK228,15104 -fastapi/param_functions.py,sha256=Tjkkmbw-gzMQAE9bh1uffMzHNxycALbL0-0QVtb-Vv0,6098 -fastapi/params.py,sha256=bq03HIlJEWMD40sSSYprP1GylmfdHh_snVW05RPinOQ,8812 -fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142 -fastapi/responses.py,sha256=tOe4BK14HGrgrxeoS0AnFZUt-ESpVn8VpcKguQFwB-E,797 -fastapi/routing.py,sha256=fpjxzTesg5BXdNTI3ikt7GUi11n6Qrqr3-zCGQ5isXg,43117 -fastapi/security/__init__.py,sha256=JNKfkNCVmvRKEvchsbPjwrI70l8R4sdMS6ZdDbWEBJo,422 -fastapi/security/__pycache__/__init__.cpython-38.pyc,, -fastapi/security/__pycache__/api_key.cpython-38.pyc,, -fastapi/security/__pycache__/base.cpython-38.pyc,, -fastapi/security/__pycache__/http.cpython-38.pyc,, -fastapi/security/__pycache__/oauth2.cpython-38.pyc,, -fastapi/security/__pycache__/open_id_connect_url.cpython-38.pyc,, -fastapi/security/__pycache__/utils.cpython-38.pyc,, -fastapi/security/api_key.py,sha256=WdgOMNWoFbEuQeteeEbifDgjhDEdXj523FE5nEqAI8k,2427 -fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141 -fastapi/security/http.py,sha256=jPDWs2V1pKeXTtCQjhXAG_ZnwTqaX_wq7Mun6uFDl30,5640 -fastapi/security/oauth2.py,sha256=4lzjuCnii5SwWduyr2QMESIN2anIofEwoaqjfdZkwjg,7789 -fastapi/security/open_id_connect_url.py,sha256=vLlY8Ek6H3_QsA4mc_UhSJ8UTp9uMOYxYKn5DD7RmJc,1055 -fastapi/security/utils.py,sha256=izlh-HBaL1VnJeOeRTQnyNgI3hgTFs73eCyLy-snb4A,266 -fastapi/staticfiles.py,sha256=LtyORy08MWAMUrDA7iReQXReBH4TvZXxwuqIvVltixg,54 -fastapi/templating.py,sha256=5IzN3tkzKFzn0mNZTJo8Si9zO3HF5nC86cJBo_Oip10,57 -fastapi/testclient.py,sha256=zkKOHE50OeEXb7VvGsTTZOVTCCfiQQ3kKTNhl43TPmk,52 -fastapi/utils.py,sha256=fRp1wBxlQOpyxN6Qux8SrplyxT-Fn_EEPXPEtXSZD5o,4965 -fastapi/websockets.py,sha256=aKYuB1D9HGUgPPV_EOOZFi7rNLW2nCPo7hVH3sGH40Q,112 diff --git a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/WHEEL b/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/WHEEL deleted file mode 100644 index b767d46b..00000000 --- a/env/lib/python3.8/site-packages/fastapi-0.61.2.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: flit 3.0.0 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/env/lib/python3.8/site-packages/fastapi/__init__.py b/env/lib/python3.8/site-packages/fastapi/__init__.py deleted file mode 100644 index 91a83d04..00000000 --- a/env/lib/python3.8/site-packages/fastapi/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -"""FastAPI framework, high performance, easy to learn, fast to code, ready for production""" - -__version__ = "0.61.2" - -from starlette import status - -from .applications import FastAPI -from .background import BackgroundTasks -from .datastructures import UploadFile -from .exceptions import HTTPException -from .param_functions import ( - Body, - Cookie, - Depends, - File, - Form, - Header, - Path, - Query, - Security, -) -from .requests import Request -from .responses import Response -from .routing import APIRouter -from .websockets import WebSocket, WebSocketDisconnect diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 7394690c6ca8b014aa4796d3b7efc7970f8caf97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 928 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 diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/background.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/background.cpython-38.pyc deleted file mode 100644 index 308151c8122b84c922288fc19329d2bc41ab4dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmYjKF>b;@5WF)f5Ryd-KH&myk;X_Uit+%OBuyH0_%`;*_TB0BY>Aif2ELJJxJ{Ls zj*2BkV5FJR?5=h`(sU*m#o>FqV*j~@dn6oQnDoe^g_f=8$K1(h>F~tRc CK}Pui diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/concurrency.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/concurrency.cpython-38.pyc deleted file mode 100644 index 9335ec6203af26b66e565dc05a78816b5d327e9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1564 zcmZ`(%WfP+6s@Z6dAP@8PZDC8$D-K;4T`515g|g6g=LH|izvc^B)w_1yYGyf=~t?1 z9FH|-f&Bq&fK7fNzrluo=oJzY62HKTQ$6-*Y(llF>h`_2PTgmH+wD3GX`||1_6V+jm~DTs&vzaDoESbzO*6Pv!Mtet#X zwRgib4G&Z5^XhJ*Nrsw&BoFkFq%bavB8A|VoaFyuZW`t!*GU=-6RC6%6|k3Mr;j4~;&_-?4Cd9*d6-1t;T2OitQNgh>ANqQpl z2*t1%0+fxpi>WrS==zKKYbzG9bzz_J8AtH!Cw;53Lpf4abNtHevJLGBb1@8-nE|F+ z#R4pT&VS@FJ79146Bx4kjR{;vdr}s%`mi?jMx@Ayf{c_x;QB(Y07#lTf5YS&wtvVw zDl+mEMewJ{$r~j)kW?1Ro8*aCh7rPtxNj+v$0R+XgVmTh*p>YVI5a0;}zql{a_f5DR_(3gU4wRg{j&e%un^XG-qIb z3!Chj#TY+d3}*H2|AHAsWs<`9ZA;$5j#9kymRrGI+cDYRJ4y6`hC?RCBFg5uS4(ac}iObax#&)FGAGvBMVEN#!AIYTDT?YaJ$ zmRM#vfE0uG3JE}|GHjK`GW?FV$-RpJ6 zf<+_BJ5cd^b8hV-u8YRCIZJ-kWl~p2`*Bvpla#hiBGt!OdSaF16LzcD5^!jZ&(|It JT>7&F{}&PFjR^n% diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/datastructures.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/datastructures.cpython-38.pyc deleted file mode 100644 index 75a60fddf87d01935dba095b38508916fe47862a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 986 zcmZuv&2AGh5VpOW&34-gslBuaM6Qu&_Q0h=2oA8aQgQBI`q zz=84ryatcqD<{s}I5FOorU*uw(b%4!&)>}1_I5&04nKY4KPe&K{o%HRcsN2ehiD{` zRFRTqv}748gDfb+ETsOPsZJSXT}oaO8OZRG$Pl{AAd6(@l=Pz?m`(bj3!YUo7at3y z#DxMEzp|iPFMK^~pifUInrvqxNM(b`e#qBP`TsF36Q}kp?@_RgNs&i1)pEC}s=Ig1jZ? zcqIwu(;)(mr$QA{SOl-T81a>8&*-mlI<8Ad4dht2t{@#1mTPEglTNB4ZA5OzP>Sln zfS!U*p_-~$Z-lX;DN<~Oo}T0g7R;cTxgE|&VEHwU zS{u$i5W~sq_e`o&-^O1+IBT6$Mz(;qj`c*po*5|+>%I^SIv8~mBiu%Eb?^GcM!xl1@N zYdKNg-{SoJM5ybR&0Gm%O29El?N?5F4s_s+UjglDX}jJ+;zzDqI39&plgq4 diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/encoders.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/encoders.cpython-38.pyc deleted file mode 100644 index 047c4833e5d747f632f7b7fc4b754a20260548c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2853 zcmZt|O^+N$wW|8Nr+cP%cXsx}NgxqI8L&M_1d~IALhJ=0fn#MI61PCD-szg%_V&lP zs>Wok8WgcPAz8AxaLHlKjXUCu_yHU^)-gzy$Pd7ZfxxToncelqU8>jby?XWPeN@$} z_ruUf@V)u_za~%D5c-EE&VKMYMj5SUQQW~+*;6`DVR%|u6S=gl$ zI}L6XZt2Bd>BoNAi92Nw2W1$CWjF4Yy|`CKan#7!#Y(vvuQs?-td;$^j}h(Ch_2JY zglwTL6mQVZ8BIOSjW>bkQD5VL`Lw68%>9&PUgm#d##?lY_K$JAopqoES*Tl%vS8xE zyb$zl(9Kr=1?m!Q+e`5GvhJsT*2|(#toY@uvx|l+|I|?$V%5p$B%Ku^%f|vpbEle> z@ON*`7`>H>1Hi){(~7cG)a>@rlnz~G{IEJw?)9`N(!GKz^9IaS=1+4jl>6>f-hdI( zjJyFO1Tsv3g9JGy?03SD=&qUJ932~TPdY4?-ialh$8fq~#D?4xX-HGr(#ps~d+uk3 z^bc+Ju>@=j&3)lWUyn*px|#XV+J$`t+Fj882hiXxXdmc5iH=0auyY!TjtE33x*2dL zCXD_~qQ!`POderYoMj}WT^dpg!!hl zfx;m9x(p;fw1Ia`YMs}BCWj7t0#*kLzZ|gJ2G6>{3or0`vL`#T3p@UagcIM`y&|w! z6>FkDu^J2hypQIQ)aT`!^A#DLtb?AF)3{j>8@+<_(9Yinh5)b7(A~@Y@E~N z&DR=DYoLj+%g<>d_b!7s{Re@twf_0~2dH8u5}SuU$o?Ip`2eE_@5%njx*TYKKyvF; z^4h87Ulx*sGfA;6;ST-{{s4Us>c)KV>%oWU4ywq9=&Kxv;ChpZW%S&K4%|21O%>kd zb+tS$d}y;va2D808oaE*D;j)VgRcQlZj!LN7D)nk(kYj{s>fdg5F2pHhStTYr{hES zh5EJXR^6GTeNM@X#xE&9=XnJeQZ=T^fXjjDW2~HgDpDbs@{?p-SCf1{Nt8XCW~qRp zpbLtMw9mRoEd6GNo@w1riy4LN0B&&5VB{4Pi%C(ZP)PI*%b=Je<-?jx@L%QPK$(TE zFW!XJ52(JNm@WWpRg2l_bV{p?^)#oiIo{4kW7e0&1rlvb*WkMSfbsH!=}j4 zMVV1H)s}LIVk%OFX;Wlcu&HhTHURAe{~Q47tYR1I?&B^t0h*YcwP&{L!q_>^zir3I zHpsbn0I~t}$RJ;uhWlUBbpJza`1Ore_4;g@5|Ld{M_2jo-spRA*cl1s&^`25+mlN#WhnZZ2mE z&laey?e=QwHE%YHvLV!Ywa;vb8FMtywUX%?#q=|hbu`dVMiv54?(`^2E0K@e{T?pK zt9n|1({&fvMM>e|S3YL)v| rS!c6?{y;x?_}c&ih>LEo6Mzu6zUgEC%fNH33o(AG=`OVA`2YGpeV@I6 diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/exception_handlers.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/exception_handlers.cpython-38.pyc deleted file mode 100644 index 4e111f00c17469fe2e22965580bffed74ae44f0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1076 zcmZXTOK;Oa5Xbl7#7UEs&{h=}ZV1VT#!}0n2UPJ;BtR&wniL6NEH^teE`G7Qsah$V z%C!3!;UQj%W{w*ZGB~5|5hhp~|ypKY{f5Mls-4rRcU_47Ufnpo%nQg3E$c@zS`hl0)LZiuy3M$Acf6r!2-q%#H z89ih%MaySQ@H0Ln*Q3HYV?(5hs%rz|P9Q>+%G3quC{8?PT1rQHs=`u!3s3Q=?AV)Q z+ygAqTFN@^W!suE!)3$zO>68E--x`0x8I3B$y4wZj8RRVfqxL|P(qO_f11U95smc( z(kNR~Adf)$kRAC+yzdt$dXi@wy-i=m8rHDxZFB(2e-mMEMeHM>Ir4B4Wg@};d&P-a zooHQzH*&Ts)kQ;Sn>v)y25|`cQ+MQTj9mk4VOwb>;5+DO3y*4q`h|Zbr!+>u7N5rl zrF@T-0E|1%GYy&coH-g7pOyA)rVe&i6c%10vTRB~(za#pRUbY)x)`vVDweTQ*;f$G zP{ZQ6TtR=}Et+mcrB_X?njgG$5&j2DNjpGh1sTc&w1(aVD<$p!&n#W0s-Bdz180`6 zCgvlpN~J;fGJ_t@jV!fWv}K2Lo&PCrJWO*jO<;>+nX*FK_-(2mUurRe8qfa%UYil$ diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/exceptions.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index 1f61f40c0a3e5a007fbe0c045e42d3f3bf39b3a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2031 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 Se`Xb94Nw1KhSlj1`Op6lex#BB diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/params.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/params.cpython-38.pyc deleted file mode 100644 index 21667ab80dc640e7a800927227d6374363b7c2dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7274 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 diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/requests.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/requests.cpython-38.pyc deleted file mode 100644 index 88b701472aec0e3ce4032fab86e7f692b3d20244..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 276 zcmYjLF;2rk5WKU4h!CNm<^wL`Eof3iC=v}7LJ*oX(Z$}xr`UJL?K)CELCYKX2G4Ly z#TTg96GCF7ot;^YH2XZ6oGHQV?PL8a`!kvU$iysU=t`(owQg0XS6U~XiOyD;==@0) zqc2IQLJt>r%jLtZcMdDI-pS?k5np;FzAy6OlGwx+nX!z&SBj}5=0fi(o+O>>a|+@;YMh1iiBmOvMd$#!U(10VAM0Kx;P;j@)>6UCw|k<5Y5cvqOTdk?LUK WueJ=wVLb1A-M4t7rIFGf=lTc3OiNY( diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/responses.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/responses.cpython-38.pyc deleted file mode 100644 index abd5c3204f105c99acd7cf6f7d0397d76a2bf38e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1063 zcmY*Y&2H2%5VrHT*=%;TrBp&lNV)Ezn*$dP2vH$^1zXe~0lq|OJZ(c0C)iHKt~k*? z05>ii;DW?!@EEyr;uSbC&VrQM%I9w;$;>xn`*1uC2#!0Se?jU!W+i@4U$Gnbv$OmlD@d0w5`5pI>581HeL*xMq zC|QM=At**{^oocZ4uSA2ke?_qlLu_{h6w95c})0-hnIwh;9l5l%!7S08~;YFWJX(i zM=Ws(ALRw?fvPK^z}Qa?UOeyH&-Qm0J$vJ2k>=t6-s_%ox(7U$koA3j@BPNUmXMaY zIO#dZhyBot%;@S5?D)F75fUJba>6W5nGFuO-1=g1n>&{d^SFz3dF^C(uODzVP3yYI zvsCAmh~KJ8%&c~hRYHT%ttUY@Qe;*yqv0m$1ANp?1dSVcHdIqhIlZ7CsU}~o5A++w zbk<@uucV0@m5tKT5k$FAIxPy|k*=afL3CBm%x=B)AMIpEDUe3jLn$lSy1XfCh4LH) z#jy-A^$#Mi;qoVoPpcAQ1sMvi1jHw~P9)ToiW`x~b(-l@C{wYG0nb6kAkO0=KZ@(6 zKCQ&<`JGth8n*Gfv-AX1e4L`lI*;YQ9ar;uX__H8$SqU1gFxt%uC}hqpRd1J%m%HW zBqA*#N!lPu%8ECI;bD@zYtrKXn-Wh%n&@Q>()6`;kCqygypFu9tOuLMH$pHKcLIFs zSe<7!X+4aA2WK5+6V=NCvNUu!GLVH33`!8XJ4u}8% diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/routing.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/routing.cpython-38.pyc deleted file mode 100644 index 514012ba0cbd827854a65b816925038366848f2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20006 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 LBhakRK+FID79TUq diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/templating.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/templating.cpython-38.pyc deleted file mode 100644 index 13aa1d3e91660bdc511fe0e0566242de7a7781a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205 zcmWIL<>g`kf~vMd@s>dPF^Gc(44TX@fuanW zjJNo`GV`($jY3j$3vv=mQj7gGnW99BOA?E6QcFrw^-3V(nR)3&AOlx26fpxSF!9Sw zza+OnzaX-6=Cq2hNKP?exQbDFZ!W6xN%3B;Zx%nxj OIjMGxK%+hbF#`aIn>2O+ diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/testclient.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/testclient.cpython-38.pyc deleted file mode 100644 index b8678348ba57b2b2db918226559756efde8e623a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmWIL<>g`kf~vMd@g_j}F^Gc(44TX@fuanW zjJLQ#Qj1HRb23x&O8hjLqC|>I5{q(DOG;ApN`Ml{V2L7-St}Wen1K|S_+_SFl3So( zkXfKxnpcpRoSmAYTb_}cnxk82kZqKco@1b&mIySdAX6Vw diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 1e234cea401d95a92fad5cc44aaa2c2966b88334..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3940 zcmai0OOM>f5oR|Z!{Klr+V`v;JCfzcIM%LVA7VR-V_CLf9kMYb%W>!jK@EF$xgt5E zCdc+}IEQ2f#5o8^00TKh0d|kRBiSFv|>gq>z)mL?A zX2vt{z4DiTgksS!{z;wbuZ7MVD8=8IVZ=tvQX{A-3mE!5<(V0njK<8=%Iv__Z7X%M zM$pLIz|ERLGxGv3YXz;$5BzKElOp*w?7ohzLR52S-q$zA?DqB`$qUK zs+%8lP365A72^6J?FryxXn(s$xg3SjKGR+%_NaLG%f1o@) zUH8?@ojex(Bo{Gl3!x<~9S-H7CyF90db=WvFustAJP~;rCPgv2TVKait$rGn^@fF- ztwr-F!x^HXa-=9nGVhTt=;J6Zii2_;rFa8XVvKoZyk&g+(%3AG%B)z4_kC!7WR9(| zJ$5R7#4G!lF{5IY**3LOICA)=pA}QVa*h)+kT5hEcC1P3Bh$AwLyzOXQz!rODl`;eNS0$Y0)kWvfU^ zaRu}4MLVL{>f_;~VX`$UleE|z?yKb;G12t&+2*l#K{qmNi@BUL4mI<~zUeWSc}!jc zr^}T!jLKcPicSxBa{5u*M$xZ9OO-~+j(E%}Q4C>pqN9(#*|`-Z zg(x~nzoWI#Nzl%<4mP#$cDEs)!>MJLs^_Wt2~{spb%m-eRCtI@kb{?Q*0P;Q?i8K= zKt8eG#m+lPUcT0WTlemD%H62!9Bj~@QAh9D8SckXUM9Wzc=}9m9I_47?2qzZIT)mP z7`$tlM5#PO4FA>$BAIww%7KJ!)TXOE@p(^ZY%7$11B2Jzy{V^koB!uVbQOIqHG872 zP^;@nLtCCe-uGuc4e{bKDr3fFKDQX$V*3BuX>sPWS>`bBvHU6KeFdcMrEuFgq*o|l z>vp~2tKfd$amZ;1!pLz0s>3vQfIF(}qn2pWK)GK~jdXQ>i1^y6nmH7o`UPamS zk7kYuIM>EjIa^scf%y=&yXRNd-W=fZpq$4!=CFxDGT?AbOT>@PK zT?SnST>)JIT?JhQT?1VMZG*N!*Z;(%`v;@XVmo#oxHR&Xamc`3NBbgq^gQSV&pVTfSlhT&a=y)cxo z-~oXDrw;Nxcq6c(ms+G(T0^yim-%>p%n)c8z1TzkXMW$pPOM&tsl|ywO^iX?0PvG< zzNngrdlM_9U8msAyP76N*&AfT*Av>xLgjG&_~6+eS#9%bI_O1d@j4nOQr%0+ijfP{ zK2FD0joqk-%2LXo(Oyeb%}_;1CJEk@36Pbu)Pg#6&<&Lr)+a2&P&shuktpQPNkS`# zEL}CRa9Ben0mqLb3i+S%fbWCP!W>?q<|d#lAo*FeUnuWX8HH-z6Z`eH%A3p^NTdS@ z#nWIuhgeun4|o6(JmOw~M8__6Bcwfx!@+Qblww-2>&VyWpyY{aW+0QD1j&;2Q{|4Z z0C}up{h$eWorVehN)&ap3f@7ZcpsJFxNv-jEudJ4k+Uc+YAQN@KAtzJ_ru@g)_1Pu zVwQy%>zdOu^d4QSR`gTYMLC&3Xpd{~pnd5hz##KDjk*Nr6n0h(%72b1$AuFgn;HQ4 zDjfZY9~;E2Oc<)UeK7OkCof)kHM(+e?Me`StXPO-hY%0Zd30CVcrziV42q8f-`XuzdQv_0i<%DRi3K!?#9YsfgX^0lg_)Y~Bj zIizy0B8?lR;&p~zK?Xs-mKy&BX>QyD diff --git a/env/lib/python3.8/site-packages/fastapi/__pycache__/websockets.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/__pycache__/websockets.cpython-38.pyc deleted file mode 100644 index 3b76ffb132eb5751e867703e360184cbb4adb50b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 287 zcmYk0F-`+95Jl}>kO)dDD7nBE*(qpJM2Lc#CPGMQBCmInwX$nlo=H$n!Wp;*$JmyN zD^M|}07jZW|4Uzb^E8`XDw)OW`zFf$$l?DK67FT`Mx<4(?$w~zT4!H~FV=AI(C0zZ62S+w|kCq>+a=a!ssYhn4U$CK{I;BiYrO2B~=h None: - self.default_response_class = default_response_class - self._debug = debug - self.state = State() - self.router: routing.APIRouter = routing.APIRouter( - routes, - dependency_overrides_provider=self, - on_startup=on_startup, - on_shutdown=on_shutdown, - ) - self.exception_handlers = ( - {} if exception_handlers is None else dict(exception_handlers) - ) - self.exception_handlers.setdefault(HTTPException, http_exception_handler) - self.exception_handlers.setdefault( - RequestValidationError, request_validation_exception_handler - ) - - self.user_middleware = [] if middleware is None else list(middleware) - self.middleware_stack = self.build_middleware_stack() - - self.title = title - self.description = description - self.version = version - self.servers = servers or [] - self.openapi_url = openapi_url - self.openapi_tags = openapi_tags - # TODO: remove when discarding the openapi_prefix parameter - if openapi_prefix: - logger.warning( - '"openapi_prefix" has been deprecated in favor of "root_path", which ' - "follows more closely the ASGI standard, is simpler, and more " - "automatic. Check the docs at " - "https://fastapi.tiangolo.com/advanced/sub-applications/" - ) - self.root_path = root_path or openapi_prefix - self.root_path_in_servers = root_path_in_servers - self.docs_url = docs_url - self.redoc_url = redoc_url - self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url - self.swagger_ui_init_oauth = swagger_ui_init_oauth - self.extra = extra - self.dependency_overrides: Dict[Callable, Callable] = {} - - self.openapi_version = "3.0.2" - - if self.openapi_url: - assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'" - assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'" - self.openapi_schema: Optional[Dict[str, Any]] = None - self.setup() - - def openapi(self) -> Dict: - if not self.openapi_schema: - self.openapi_schema = get_openapi( - title=self.title, - version=self.version, - openapi_version=self.openapi_version, - description=self.description, - routes=self.routes, - tags=self.openapi_tags, - servers=self.servers, - ) - return self.openapi_schema - - def setup(self) -> None: - if self.openapi_url: - urls = (server_data.get("url") for server_data in self.servers) - server_urls = {url for url in urls if url} - - async def openapi(req: Request) -> JSONResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - if root_path not in server_urls: - if root_path and self.root_path_in_servers: - self.servers.insert(0, {"url": root_path}) - server_urls.add(root_path) - return JSONResponse(self.openapi()) - - self.add_route(self.openapi_url, openapi, include_in_schema=False) - if self.openapi_url and self.docs_url: - - async def swagger_ui_html(req: Request) -> HTMLResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - openapi_url = root_path + self.openapi_url - oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url - if oauth2_redirect_url: - oauth2_redirect_url = root_path + oauth2_redirect_url - return get_swagger_ui_html( - openapi_url=openapi_url, - title=self.title + " - Swagger UI", - oauth2_redirect_url=oauth2_redirect_url, - init_oauth=self.swagger_ui_init_oauth, - ) - - self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False) - - if self.swagger_ui_oauth2_redirect_url: - - async def swagger_ui_redirect(req: Request) -> HTMLResponse: - return get_swagger_ui_oauth2_redirect_html() - - self.add_route( - self.swagger_ui_oauth2_redirect_url, - swagger_ui_redirect, - include_in_schema=False, - ) - if self.openapi_url and self.redoc_url: - - async def redoc_html(req: Request) -> HTMLResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - openapi_url = root_path + self.openapi_url - return get_redoc_html( - openapi_url=openapi_url, title=self.title + " - ReDoc" - ) - - self.add_route(self.redoc_url, redoc_html, include_in_schema=False) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if self.root_path: - scope["root_path"] = self.root_path - if AsyncExitStack: - async with AsyncExitStack() as stack: - scope["fastapi_astack"] = stack - await super().__call__(scope, receive, send) - else: - await super().__call__(scope, receive, send) # pragma: no cover - - def add_api_route( - self, - path: str, - endpoint: Callable, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - methods: Optional[List[str]] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - ) -> None: - self.router.add_api_route( - path, - endpoint=endpoint, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - ) - - def api_route( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - methods: Optional[List[str]] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - ) -> Callable: - def decorator(func: Callable) -> Callable: - self.router.add_api_route( - path, - func, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - ) - return func - - return decorator - - def add_api_websocket_route( - self, path: str, endpoint: Callable, name: Optional[str] = None - ) -> None: - self.router.add_api_websocket_route(path, endpoint, name=name) - - def websocket(self, path: str, name: Optional[str] = None) -> Callable: - def decorator(func: Callable) -> Callable: - self.add_api_websocket_route(path, func, name=name) - return func - - return decorator - - def include_router( - self, - router: routing.APIRouter, - *, - prefix: str = "", - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - default_response_class: Optional[Type[Response]] = None, - ) -> None: - self.router.include_router( - router, - prefix=prefix, - tags=tags, - dependencies=dependencies, - responses=responses or {}, - default_response_class=default_response_class - or self.default_response_class, - ) - - def get( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.get( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def put( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.put( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def post( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.post( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def delete( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.delete( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - operation_id=operation_id, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def options( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.options( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def head( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.head( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def patch( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.patch( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def trace( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[routing.APIRoute]] = None, - ) -> Callable: - return self.router.trace( - path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) diff --git a/env/lib/python3.8/site-packages/fastapi/background.py b/env/lib/python3.8/site-packages/fastapi/background.py deleted file mode 100644 index 2d0d3d35..00000000 --- a/env/lib/python3.8/site-packages/fastapi/background.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.background import BackgroundTasks # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/concurrency.py b/env/lib/python3.8/site-packages/fastapi/concurrency.py deleted file mode 100644 index 451923c5..00000000 --- a/env/lib/python3.8/site-packages/fastapi/concurrency.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Callable - -from starlette.concurrency import iterate_in_threadpool # noqa -from starlette.concurrency import run_in_threadpool # noqa -from starlette.concurrency import run_until_first_complete # noqa - -asynccontextmanager_error_message = """ -FastAPI's contextmanager_in_threadpool require Python 3.7 or above, -or the backport for Python 3.6, installed with: - pip install async-generator -""" - - -def _fake_asynccontextmanager(func: Callable) -> Callable: - def raiser(*args: Any, **kwargs: Any) -> Any: - raise RuntimeError(asynccontextmanager_error_message) - - return raiser - - -try: - from contextlib import asynccontextmanager # type: ignore -except ImportError: - try: - from async_generator import asynccontextmanager # type: ignore - except ImportError: # pragma: no cover - asynccontextmanager = _fake_asynccontextmanager - -try: - from contextlib import AsyncExitStack # type: ignore -except ImportError: - try: - from async_exit_stack import AsyncExitStack # type: ignore - except ImportError: # pragma: no cover - AsyncExitStack = None # type: ignore - - -@asynccontextmanager -async def contextmanager_in_threadpool(cm: Any) -> Any: - try: - yield await run_in_threadpool(cm.__enter__) - except Exception as e: - ok = await run_in_threadpool(cm.__exit__, type(e), e, None) - if not ok: - raise e - else: - await run_in_threadpool(cm.__exit__, None, None, None) diff --git a/env/lib/python3.8/site-packages/fastapi/datastructures.py b/env/lib/python3.8/site-packages/fastapi/datastructures.py deleted file mode 100644 index 1ee99001..00000000 --- a/env/lib/python3.8/site-packages/fastapi/datastructures.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Any, Callable, Iterable, Type - -from starlette.datastructures import UploadFile as StarletteUploadFile - - -class UploadFile(StarletteUploadFile): - @classmethod - def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable]: - yield cls.validate - - @classmethod - def validate(cls: Type["UploadFile"], v: Any) -> Any: - if not isinstance(v, StarletteUploadFile): - raise ValueError(f"Expected UploadFile, received: {type(v)}") - return v diff --git a/env/lib/python3.8/site-packages/fastapi/dependencies/__init__.py b/env/lib/python3.8/site-packages/fastapi/dependencies/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index be5b482feadb0f7e4b47248e9bc84c201beca9a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202 zcmYk0F%H5o3`J9k0U`Au46O&24hV4q7Q`Hd#IzBu6D4V-o`f@S4UWOe5!je;Civ2S zmcOhopUQG2Sk3Jr^L%CetKenNjthnnN3kvrcM)>@!^c7A284(@U~+`e+9U&d7hxm| zUg^}~ps0!%CJcZyL2u9C=hQjc)D1+Nu;RO`YB9n^#iYCigC5BsY0IIMmbg~dets^u NgEM1~yZp$TExs9BH<3M}#|p)U2#3H6@Y zQ5!U$wm@rv)}g@(8Ml7}t7Poz;8Bw2$uwu${VbD82VZcNRb`Uv;DkM1urg(1OZQG# zx)7OKK1?L)ozE-E@=r3B(-aLg9}kox81g*;Mk0%n$fh21n9Dro?~{FS`og9TbRe<@+4Jo zd{RD;Ogv#CWaX1E&!!tMt>bZkJIkbCajZLW3rxo2S?KRV{w_mDdsa;H%c2np< zJrvk)QmqV`B@bYjz)g)9nRVP7`QF?P7$+Be4gSAYMbbjj)e!fN%%lF2d^wZy?-5 zcoX3*gtrmiLAa0bE&|eqcppIf(25IDrWPpp3}K95U{RY^{}F`R;{J@R+MRD3$*LWG zU?jVC`F$ffwZ|t$a%-O-8p*3${GpNjx&szkbr&$Gdw}h_57?=<0K4@zV6Pqk_Uiy} zt8N1h>RW)@^$-xGZwG3qMrsG79{*uRo>};wA_?sx35g!KJKnoFVA1X-9as;SOekL+ zI1@7yy{jl+h0s$A4&3g`N+?Ew37Cr7CV%l6TSE5w;M2_>{ht)R%r!_tILzHZ_BvMc z^{s2K?b}a>o5s9i!mhZ5eq%uhtcVraIVd5O8SWB0DB-oB-Dy?juVz3bHKam$3=p`$ zfB*LW;W|yvJJ&q#fCb;Oe-~)`c-+;#TJo%%8GnRvbi>cl?&W1MS*Lz7g=^NZxE}B& r1y0J+$tm8pvhn}WbR)ocjS2i4I{0vPFMNcJBaz>4+dZr2Yz2P-gg5J} diff --git a/env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/dependencies/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 53b77a2554e1683c828232bae323c9b18efb824c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18102 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 None: - self.path_params = path_params or [] - self.query_params = query_params or [] - self.header_params = header_params or [] - self.cookie_params = cookie_params or [] - self.body_params = body_params or [] - self.dependencies = dependencies or [] - self.security_requirements = security_schemes or [] - self.request_param_name = request_param_name - self.websocket_param_name = websocket_param_name - self.http_connection_param_name = http_connection_param_name - self.response_param_name = response_param_name - self.background_tasks_param_name = background_tasks_param_name - self.security_scopes = security_scopes - self.security_scopes_param_name = security_scopes_param_name - self.name = name - self.call = call - self.use_cache = use_cache - # Store the path to be able to re-generate a dependable from it in overrides - self.path = path - # Save the cache key at creation to optimize performance - self.cache_key = (self.call, tuple(sorted(set(self.security_scopes or [])))) diff --git a/env/lib/python3.8/site-packages/fastapi/dependencies/utils.py b/env/lib/python3.8/site-packages/fastapi/dependencies/utils.py deleted file mode 100644 index 35329a46..00000000 --- a/env/lib/python3.8/site-packages/fastapi/dependencies/utils.py +++ /dev/null @@ -1,785 +0,0 @@ -import asyncio -import inspect -from contextlib import contextmanager -from copy import deepcopy -from typing import ( - Any, - Callable, - Dict, - List, - Mapping, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) - -from fastapi import params -from fastapi.concurrency import ( - AsyncExitStack, - _fake_asynccontextmanager, - asynccontextmanager, - contextmanager_in_threadpool, -) -from fastapi.dependencies.models import Dependant, SecurityRequirement -from fastapi.logger import logger -from fastapi.security.base import SecurityBase -from fastapi.security.oauth2 import OAuth2, SecurityScopes -from fastapi.security.open_id_connect_url import OpenIdConnect -from fastapi.utils import create_response_field, get_path_param_names -from pydantic import BaseModel, create_model -from pydantic.error_wrappers import ErrorWrapper -from pydantic.errors import MissingError -from pydantic.fields import ( - SHAPE_LIST, - SHAPE_SEQUENCE, - SHAPE_SET, - SHAPE_SINGLETON, - SHAPE_TUPLE, - SHAPE_TUPLE_ELLIPSIS, - FieldInfo, - ModelField, - Required, -) -from pydantic.schema import get_annotation_from_field_info -from pydantic.typing import ForwardRef, evaluate_forwardref -from pydantic.utils import lenient_issubclass -from starlette.background import BackgroundTasks -from starlette.concurrency import run_in_threadpool -from starlette.datastructures import FormData, Headers, QueryParams, UploadFile -from starlette.requests import HTTPConnection, Request -from starlette.responses import Response -from starlette.websockets import WebSocket - -sequence_shapes = { - SHAPE_LIST, - SHAPE_SET, - SHAPE_TUPLE, - SHAPE_SEQUENCE, - SHAPE_TUPLE_ELLIPSIS, -} -sequence_types = (list, set, tuple) -sequence_shape_to_type = { - SHAPE_LIST: list, - SHAPE_SET: set, - SHAPE_TUPLE: tuple, - SHAPE_SEQUENCE: list, - SHAPE_TUPLE_ELLIPSIS: list, -} - - -multipart_not_installed_error = ( - 'Form data requires "python-multipart" to be installed. \n' - 'You can install "python-multipart" with: \n\n' - "pip install python-multipart\n" -) -multipart_incorrect_install_error = ( - 'Form data requires "python-multipart" to be installed. ' - 'It seems you installed "multipart" instead. \n' - 'You can remove "multipart" with: \n\n' - "pip uninstall multipart\n\n" - 'And then install "python-multipart" with: \n\n' - "pip install python-multipart\n" -) - - -def check_file_field(field: ModelField) -> None: - field_info = field.field_info - if isinstance(field_info, params.Form): - try: - # __version__ is available in both multiparts, and can be mocked - from multipart import __version__ - - assert __version__ - try: - # parse_options_header is only available in the right multipart - from multipart.multipart import parse_options_header - - assert parse_options_header - except ImportError: - logger.error(multipart_incorrect_install_error) - raise RuntimeError(multipart_incorrect_install_error) - except ImportError: - logger.error(multipart_not_installed_error) - raise RuntimeError(multipart_not_installed_error) - - -def get_param_sub_dependant( - *, param: inspect.Parameter, path: str, security_scopes: Optional[List[str]] = None -) -> Dependant: - depends: params.Depends = param.default - if depends.dependency: - dependency = depends.dependency - else: - dependency = param.annotation - return get_sub_dependant( - depends=depends, - dependency=dependency, - path=path, - name=param.name, - security_scopes=security_scopes, - ) - - -def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant: - assert callable( - depends.dependency - ), "A parameter-less dependency must have a callable dependency" - return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path) - - -def get_sub_dependant( - *, - depends: params.Depends, - dependency: Callable, - path: str, - name: Optional[str] = None, - security_scopes: Optional[List[str]] = None, -) -> Dependant: - security_requirement = None - security_scopes = security_scopes or [] - if isinstance(depends, params.Security): - dependency_scopes = depends.scopes - security_scopes.extend(dependency_scopes) - if isinstance(dependency, SecurityBase): - use_scopes: List[str] = [] - if isinstance(dependency, (OAuth2, OpenIdConnect)): - use_scopes = security_scopes - security_requirement = SecurityRequirement( - security_scheme=dependency, scopes=use_scopes - ) - sub_dependant = get_dependant( - path=path, - call=dependency, - name=name, - security_scopes=security_scopes, - use_cache=depends.use_cache, - ) - if security_requirement: - sub_dependant.security_requirements.append(security_requirement) - sub_dependant.security_scopes = security_scopes - return sub_dependant - - -CacheKey = Tuple[Optional[Callable], Tuple[str, ...]] - - -def get_flat_dependant( - dependant: Dependant, - *, - skip_repeats: bool = False, - visited: Optional[List[CacheKey]] = None, -) -> Dependant: - if visited is None: - visited = [] - visited.append(dependant.cache_key) - - flat_dependant = Dependant( - path_params=dependant.path_params.copy(), - query_params=dependant.query_params.copy(), - header_params=dependant.header_params.copy(), - cookie_params=dependant.cookie_params.copy(), - body_params=dependant.body_params.copy(), - security_schemes=dependant.security_requirements.copy(), - use_cache=dependant.use_cache, - path=dependant.path, - ) - for sub_dependant in dependant.dependencies: - if skip_repeats and sub_dependant.cache_key in visited: - continue - flat_sub = get_flat_dependant( - sub_dependant, skip_repeats=skip_repeats, visited=visited - ) - flat_dependant.path_params.extend(flat_sub.path_params) - flat_dependant.query_params.extend(flat_sub.query_params) - flat_dependant.header_params.extend(flat_sub.header_params) - flat_dependant.cookie_params.extend(flat_sub.cookie_params) - flat_dependant.body_params.extend(flat_sub.body_params) - flat_dependant.security_requirements.extend(flat_sub.security_requirements) - return flat_dependant - - -def get_flat_params(dependant: Dependant) -> List[ModelField]: - flat_dependant = get_flat_dependant(dependant, skip_repeats=True) - return ( - flat_dependant.path_params - + flat_dependant.query_params - + flat_dependant.header_params - + flat_dependant.cookie_params - ) - - -def is_scalar_field(field: ModelField) -> bool: - field_info = field.field_info - if not ( - field.shape == SHAPE_SINGLETON - and not lenient_issubclass(field.type_, BaseModel) - and not lenient_issubclass(field.type_, sequence_types + (dict,)) - and not isinstance(field_info, params.Body) - ): - return False - if field.sub_fields: - if not all(is_scalar_field(f) for f in field.sub_fields): - return False - return True - - -def is_scalar_sequence_field(field: ModelField) -> bool: - if (field.shape in sequence_shapes) and not lenient_issubclass( - field.type_, BaseModel - ): - if field.sub_fields is not None: - for sub_field in field.sub_fields: - if not is_scalar_field(sub_field): - return False - return True - if lenient_issubclass(field.type_, sequence_types): - return True - return False - - -def get_typed_signature(call: Callable) -> inspect.Signature: - signature = inspect.signature(call) - globalns = getattr(call, "__globals__", {}) - typed_params = [ - inspect.Parameter( - name=param.name, - kind=param.kind, - default=param.default, - annotation=get_typed_annotation(param, globalns), - ) - for param in signature.parameters.values() - ] - typed_signature = inspect.Signature(typed_params) - return typed_signature - - -def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any: - annotation = param.annotation - if isinstance(annotation, str): - # Temporary ignore type - # Ref: https://github.com/samuelcolvin/pydantic/issues/1738 - annotation = ForwardRef(annotation) # type: ignore - annotation = evaluate_forwardref(annotation, globalns, globalns) - return annotation - - -async_contextmanager_dependencies_error = """ -FastAPI dependencies with yield require Python 3.7 or above, -or the backports for Python 3.6, installed with: - pip install async-exit-stack async-generator -""" - - -def check_dependency_contextmanagers() -> None: - if AsyncExitStack is None or asynccontextmanager == _fake_asynccontextmanager: - raise RuntimeError(async_contextmanager_dependencies_error) # pragma: no cover - - -def get_dependant( - *, - path: str, - call: Callable, - name: Optional[str] = None, - security_scopes: Optional[List[str]] = None, - use_cache: bool = True, -) -> Dependant: - path_param_names = get_path_param_names(path) - endpoint_signature = get_typed_signature(call) - signature_params = endpoint_signature.parameters - if is_gen_callable(call) or is_async_gen_callable(call): - check_dependency_contextmanagers() - dependant = Dependant(call=call, name=name, path=path, use_cache=use_cache) - for param_name, param in signature_params.items(): - if isinstance(param.default, params.Depends): - sub_dependant = get_param_sub_dependant( - param=param, path=path, security_scopes=security_scopes - ) - dependant.dependencies.append(sub_dependant) - continue - if add_non_field_param_to_dependency(param=param, dependant=dependant): - continue - param_field = get_param_field( - param=param, default_field_info=params.Query, param_name=param_name - ) - if param_name in path_param_names: - assert is_scalar_field( - field=param_field - ), "Path params must be of one of the supported types" - if isinstance(param.default, params.Path): - ignore_default = False - else: - ignore_default = True - param_field = get_param_field( - param=param, - param_name=param_name, - default_field_info=params.Path, - force_type=params.ParamTypes.path, - ignore_default=ignore_default, - ) - add_param_to_fields(field=param_field, dependant=dependant) - elif is_scalar_field(field=param_field): - add_param_to_fields(field=param_field, dependant=dependant) - elif isinstance( - param.default, (params.Query, params.Header) - ) and is_scalar_sequence_field(param_field): - add_param_to_fields(field=param_field, dependant=dependant) - else: - field_info = param_field.field_info - assert isinstance( - field_info, params.Body - ), f"Param: {param_field.name} can only be a request body, using Body(...)" - dependant.body_params.append(param_field) - return dependant - - -def add_non_field_param_to_dependency( - *, param: inspect.Parameter, dependant: Dependant -) -> Optional[bool]: - if lenient_issubclass(param.annotation, Request): - dependant.request_param_name = param.name - return True - elif lenient_issubclass(param.annotation, WebSocket): - dependant.websocket_param_name = param.name - return True - elif lenient_issubclass(param.annotation, HTTPConnection): - dependant.http_connection_param_name = param.name - return True - elif lenient_issubclass(param.annotation, Response): - dependant.response_param_name = param.name - return True - elif lenient_issubclass(param.annotation, BackgroundTasks): - dependant.background_tasks_param_name = param.name - return True - elif lenient_issubclass(param.annotation, SecurityScopes): - dependant.security_scopes_param_name = param.name - return True - return None - - -def get_param_field( - *, - param: inspect.Parameter, - param_name: str, - default_field_info: Type[params.Param] = params.Param, - force_type: Optional[params.ParamTypes] = None, - ignore_default: bool = False, -) -> ModelField: - default_value = Required - had_schema = False - if not param.default == param.empty and ignore_default is False: - default_value = param.default - if isinstance(default_value, FieldInfo): - had_schema = True - field_info = default_value - default_value = field_info.default - if ( - isinstance(field_info, params.Param) - and getattr(field_info, "in_", None) is None - ): - field_info.in_ = default_field_info.in_ - if force_type: - field_info.in_ = force_type # type: ignore - else: - field_info = default_field_info(default_value) - required = default_value == Required - annotation: Any = Any - if not param.annotation == param.empty: - annotation = param.annotation - annotation = get_annotation_from_field_info(annotation, field_info, param_name) - if not field_info.alias and getattr(field_info, "convert_underscores", None): - alias = param.name.replace("_", "-") - else: - alias = field_info.alias or param.name - field = create_response_field( - name=param.name, - type_=annotation, - default=None if required else default_value, - alias=alias, - required=required, - field_info=field_info, - ) - field.required = required - if not had_schema and not is_scalar_field(field=field): - field.field_info = params.Body(field_info.default) - - return field - - -def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: - field_info = cast(params.Param, field.field_info) - if field_info.in_ == params.ParamTypes.path: - dependant.path_params.append(field) - elif field_info.in_ == params.ParamTypes.query: - dependant.query_params.append(field) - elif field_info.in_ == params.ParamTypes.header: - dependant.header_params.append(field) - else: - assert ( - field_info.in_ == params.ParamTypes.cookie - ), f"non-body parameters must be in path, query, header or cookie: {field.name}" - dependant.cookie_params.append(field) - - -def is_coroutine_callable(call: Callable) -> bool: - if inspect.isroutine(call): - return inspect.iscoroutinefunction(call) - if inspect.isclass(call): - return False - call = getattr(call, "__call__", None) - return inspect.iscoroutinefunction(call) - - -def is_async_gen_callable(call: Callable) -> bool: - if inspect.isasyncgenfunction(call): - return True - call = getattr(call, "__call__", None) - return inspect.isasyncgenfunction(call) - - -def is_gen_callable(call: Callable) -> bool: - if inspect.isgeneratorfunction(call): - return True - call = getattr(call, "__call__", None) - return inspect.isgeneratorfunction(call) - - -async def solve_generator( - *, call: Callable, stack: AsyncExitStack, sub_values: Dict[str, Any] -) -> Any: - if is_gen_callable(call): - cm = contextmanager_in_threadpool(contextmanager(call)(**sub_values)) - elif is_async_gen_callable(call): - if not inspect.isasyncgenfunction(call): - # asynccontextmanager from the async_generator backfill pre python3.7 - # does not support callables that are not functions or methods. - # See https://github.com/python-trio/async_generator/issues/32 - # - # Expand the callable class into its __call__ method before decorating it. - # This approach will work on newer python versions as well. - call = getattr(call, "__call__", None) - cm = asynccontextmanager(call)(**sub_values) - return await stack.enter_async_context(cm) - - -async def solve_dependencies( - *, - request: Union[Request, WebSocket], - dependant: Dependant, - body: Optional[Union[Dict[str, Any], FormData]] = None, - background_tasks: Optional[BackgroundTasks] = None, - response: Optional[Response] = None, - dependency_overrides_provider: Optional[Any] = None, - dependency_cache: Optional[Dict[Tuple[Callable, Tuple[str]], Any]] = None, -) -> Tuple[ - Dict[str, Any], - List[ErrorWrapper], - Optional[BackgroundTasks], - Response, - Dict[Tuple[Callable, Tuple[str]], Any], -]: - values: Dict[str, Any] = {} - errors: List[ErrorWrapper] = [] - response = response or Response( - content=None, - status_code=None, # type: ignore - headers=None, - media_type=None, - background=None, - ) - dependency_cache = dependency_cache or {} - sub_dependant: Dependant - for sub_dependant in dependant.dependencies: - sub_dependant.call = cast(Callable, sub_dependant.call) - sub_dependant.cache_key = cast( - Tuple[Callable, Tuple[str]], sub_dependant.cache_key - ) - call = sub_dependant.call - use_sub_dependant = sub_dependant - if ( - dependency_overrides_provider - and dependency_overrides_provider.dependency_overrides - ): - original_call = sub_dependant.call - call = getattr( - dependency_overrides_provider, "dependency_overrides", {} - ).get(original_call, original_call) - use_path: str = sub_dependant.path # type: ignore - use_sub_dependant = get_dependant( - path=use_path, - call=call, - name=sub_dependant.name, - security_scopes=sub_dependant.security_scopes, - ) - use_sub_dependant.security_scopes = sub_dependant.security_scopes - - solved_result = await solve_dependencies( - request=request, - dependant=use_sub_dependant, - body=body, - background_tasks=background_tasks, - response=response, - dependency_overrides_provider=dependency_overrides_provider, - dependency_cache=dependency_cache, - ) - ( - sub_values, - sub_errors, - background_tasks, - _, # the subdependency returns the same response we have - sub_dependency_cache, - ) = solved_result - dependency_cache.update(sub_dependency_cache) - if sub_errors: - errors.extend(sub_errors) - continue - if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache: - solved = dependency_cache[sub_dependant.cache_key] - elif is_gen_callable(call) or is_async_gen_callable(call): - stack = request.scope.get("fastapi_astack") - if stack is None: - raise RuntimeError( - async_contextmanager_dependencies_error - ) # pragma: no cover - solved = await solve_generator( - call=call, stack=stack, sub_values=sub_values - ) - elif is_coroutine_callable(call): - solved = await call(**sub_values) - else: - solved = await run_in_threadpool(call, **sub_values) - if sub_dependant.name is not None: - values[sub_dependant.name] = solved - if sub_dependant.cache_key not in dependency_cache: - dependency_cache[sub_dependant.cache_key] = solved - path_values, path_errors = request_params_to_args( - dependant.path_params, request.path_params - ) - query_values, query_errors = request_params_to_args( - dependant.query_params, request.query_params - ) - header_values, header_errors = request_params_to_args( - dependant.header_params, request.headers - ) - cookie_values, cookie_errors = request_params_to_args( - dependant.cookie_params, request.cookies - ) - values.update(path_values) - values.update(query_values) - values.update(header_values) - values.update(cookie_values) - errors += path_errors + query_errors + header_errors + cookie_errors - if dependant.body_params: - ( - body_values, - body_errors, - ) = await request_body_to_args( # body_params checked above - required_params=dependant.body_params, received_body=body - ) - values.update(body_values) - errors.extend(body_errors) - if dependant.http_connection_param_name: - values[dependant.http_connection_param_name] = request - if dependant.request_param_name and isinstance(request, Request): - values[dependant.request_param_name] = request - elif dependant.websocket_param_name and isinstance(request, WebSocket): - values[dependant.websocket_param_name] = request - if dependant.background_tasks_param_name: - if background_tasks is None: - background_tasks = BackgroundTasks() - values[dependant.background_tasks_param_name] = background_tasks - if dependant.response_param_name: - values[dependant.response_param_name] = response - if dependant.security_scopes_param_name: - values[dependant.security_scopes_param_name] = SecurityScopes( - scopes=dependant.security_scopes - ) - return values, errors, background_tasks, response, dependency_cache - - -def request_params_to_args( - required_params: Sequence[ModelField], - received_params: Union[Mapping[str, Any], QueryParams, Headers], -) -> Tuple[Dict[str, Any], List[ErrorWrapper]]: - values = {} - errors = [] - for field in required_params: - if is_scalar_sequence_field(field) and isinstance( - received_params, (QueryParams, Headers) - ): - value = received_params.getlist(field.alias) or field.default - else: - value = received_params.get(field.alias) - field_info = field.field_info - assert isinstance( - field_info, params.Param - ), "Params must be subclasses of Param" - if value is None: - if field.required: - errors.append( - ErrorWrapper( - MissingError(), loc=(field_info.in_.value, field.alias) - ) - ) - else: - values[field.name] = deepcopy(field.default) - continue - v_, errors_ = field.validate( - value, values, loc=(field_info.in_.value, field.alias) - ) - if isinstance(errors_, ErrorWrapper): - errors.append(errors_) - elif isinstance(errors_, list): - errors.extend(errors_) - else: - values[field.name] = v_ - return values, errors - - -async def request_body_to_args( - required_params: List[ModelField], - received_body: Optional[Union[Dict[str, Any], FormData]], -) -> Tuple[Dict[str, Any], List[ErrorWrapper]]: - values = {} - errors = [] - if required_params: - field = required_params[0] - field_info = field.field_info - embed = getattr(field_info, "embed", None) - field_alias_omitted = len(required_params) == 1 and not embed - if field_alias_omitted: - received_body = {field.alias: received_body} - - for field in required_params: - loc: Tuple[str, ...] - if field_alias_omitted: - loc = ("body",) - else: - loc = ("body", field.alias) - - value: Optional[Any] = None - if received_body is not None: - if ( - field.shape in sequence_shapes or field.type_ in sequence_types - ) and isinstance(received_body, FormData): - value = received_body.getlist(field.alias) - else: - try: - value = received_body.get(field.alias) - except AttributeError: - errors.append(get_missing_field_error(loc)) - continue - if ( - value is None - or (isinstance(field_info, params.Form) and value == "") - or ( - isinstance(field_info, params.Form) - and field.shape in sequence_shapes - and len(value) == 0 - ) - ): - if field.required: - errors.append(get_missing_field_error(loc)) - else: - values[field.name] = deepcopy(field.default) - continue - if ( - isinstance(field_info, params.File) - and lenient_issubclass(field.type_, bytes) - and isinstance(value, UploadFile) - ): - value = await value.read() - elif ( - field.shape in sequence_shapes - and isinstance(field_info, params.File) - and lenient_issubclass(field.type_, bytes) - and isinstance(value, sequence_types) - ): - awaitables = [sub_value.read() for sub_value in value] - contents = await asyncio.gather(*awaitables) - value = sequence_shape_to_type[field.shape](contents) - - v_, errors_ = field.validate(value, values, loc=loc) - - if isinstance(errors_, ErrorWrapper): - errors.append(errors_) - elif isinstance(errors_, list): - errors.extend(errors_) - else: - values[field.name] = v_ - return values, errors - - -def get_missing_field_error(loc: Tuple[str, ...]) -> ErrorWrapper: - missing_field_error = ErrorWrapper(MissingError(), loc=loc) - return missing_field_error - - -def get_schema_compatible_field(*, field: ModelField) -> ModelField: - out_field = field - if lenient_issubclass(field.type_, UploadFile): - use_type: type = bytes - if field.shape in sequence_shapes: - use_type = List[bytes] - out_field = create_response_field( - name=field.name, - type_=use_type, - class_validators=field.class_validators, - model_config=field.model_config, - default=field.default, - required=field.required, - alias=field.alias, - field_info=field.field_info, - ) - return out_field - - -def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]: - flat_dependant = get_flat_dependant(dependant) - if not flat_dependant.body_params: - return None - first_param = flat_dependant.body_params[0] - field_info = first_param.field_info - embed = getattr(field_info, "embed", None) - body_param_names_set = {param.name for param in flat_dependant.body_params} - if len(body_param_names_set) == 1 and not embed: - final_field = get_schema_compatible_field(field=first_param) - check_file_field(final_field) - return final_field - # If one field requires to embed, all have to be embedded - # in case a sub-dependency is evaluated with a single unique body field - # That is combined (embedded) with other body fields - for param in flat_dependant.body_params: - setattr(param.field_info, "embed", True) - model_name = "Body_" + name - BodyModel = create_model(model_name) - for f in flat_dependant.body_params: - BodyModel.__fields__[f.name] = get_schema_compatible_field(field=f) - required = any(True for f in flat_dependant.body_params if f.required) - - BodyFieldInfo_kwargs: Dict[str, Any] = dict(default=None) - if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params): - BodyFieldInfo: Type[params.Body] = params.File - elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params): - BodyFieldInfo = params.Form - else: - BodyFieldInfo = params.Body - - body_param_media_types = [ - getattr(f.field_info, "media_type") - for f in flat_dependant.body_params - if isinstance(f.field_info, params.Body) - ] - if len(set(body_param_media_types)) == 1: - BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0] - final_field = create_response_field( - name="body", - type_=BodyModel, - required=required, - alias="body", - field_info=BodyFieldInfo(**BodyFieldInfo_kwargs), - ) - check_file_field(final_field) - return final_field diff --git a/env/lib/python3.8/site-packages/fastapi/encoders.py b/env/lib/python3.8/site-packages/fastapi/encoders.py deleted file mode 100644 index 1255b749..00000000 --- a/env/lib/python3.8/site-packages/fastapi/encoders.py +++ /dev/null @@ -1,148 +0,0 @@ -from collections import defaultdict -from enum import Enum -from pathlib import PurePath -from types import GeneratorType -from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union - -from pydantic import BaseModel -from pydantic.json import ENCODERS_BY_TYPE - -SetIntStr = Set[Union[int, str]] -DictIntStrAny = Dict[Union[int, str], Any] - - -def generate_encoders_by_class_tuples( - type_encoder_map: Dict[Any, Callable] -) -> Dict[Callable, Tuple]: - encoders_by_class_tuples: Dict[Callable, Tuple] = defaultdict(tuple) - for type_, encoder in type_encoder_map.items(): - encoders_by_class_tuples[encoder] += (type_,) - return encoders_by_class_tuples - - -encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE) - - -def jsonable_encoder( - obj: Any, - include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - by_alias: bool = True, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - custom_encoder: dict = {}, - sqlalchemy_safe: bool = True, -) -> Any: - if include is not None and not isinstance(include, set): - include = set(include) - if exclude is not None and not isinstance(exclude, set): - exclude = set(exclude) - if isinstance(obj, BaseModel): - encoder = getattr(obj.__config__, "json_encoders", {}) - if custom_encoder: - encoder.update(custom_encoder) - obj_dict = obj.dict( - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_none=exclude_none, - exclude_defaults=exclude_defaults, - ) - if "__root__" in obj_dict: - obj_dict = obj_dict["__root__"] - return jsonable_encoder( - obj_dict, - exclude_none=exclude_none, - exclude_defaults=exclude_defaults, - custom_encoder=encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - if isinstance(obj, Enum): - return obj.value - if isinstance(obj, PurePath): - return str(obj) - if isinstance(obj, (str, int, float, type(None))): - return obj - if isinstance(obj, dict): - encoded_dict = {} - for key, value in obj.items(): - if ( - ( - not sqlalchemy_safe - or (not isinstance(key, str)) - or (not key.startswith("_sa")) - ) - and (value is not None or not exclude_none) - and ((include and key in include) or not exclude or key not in exclude) - ): - encoded_key = jsonable_encoder( - key, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - encoded_value = jsonable_encoder( - value, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - encoded_dict[encoded_key] = encoded_value - return encoded_dict - if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)): - encoded_list = [] - for item in obj: - encoded_list.append( - jsonable_encoder( - item, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - ) - return encoded_list - - if custom_encoder: - if type(obj) in custom_encoder: - return custom_encoder[type(obj)](obj) - else: - for encoder_type, encoder in custom_encoder.items(): - if isinstance(obj, encoder_type): - return encoder(obj) - - if type(obj) in ENCODERS_BY_TYPE: - return ENCODERS_BY_TYPE[type(obj)](obj) - for encoder, classes_tuple in encoders_by_class_tuples.items(): - if isinstance(obj, classes_tuple): - return encoder(obj) - - errors: List[Exception] = [] - try: - data = dict(obj) - except Exception as e: - errors.append(e) - try: - data = vars(obj) - except Exception as e: - errors.append(e) - raise ValueError(errors) - return jsonable_encoder( - data, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) diff --git a/env/lib/python3.8/site-packages/fastapi/exception_handlers.py b/env/lib/python3.8/site-packages/fastapi/exception_handlers.py deleted file mode 100644 index 2b286d71..00000000 --- a/env/lib/python3.8/site-packages/fastapi/exception_handlers.py +++ /dev/null @@ -1,25 +0,0 @@ -from fastapi.encoders import jsonable_encoder -from fastapi.exceptions import RequestValidationError -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.responses import JSONResponse -from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY - - -async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse: - headers = getattr(exc, "headers", None) - if headers: - return JSONResponse( - {"detail": exc.detail}, status_code=exc.status_code, headers=headers - ) - else: - return JSONResponse({"detail": exc.detail}, status_code=exc.status_code) - - -async def request_validation_exception_handler( - request: Request, exc: RequestValidationError -) -> JSONResponse: - return JSONResponse( - status_code=HTTP_422_UNPROCESSABLE_ENTITY, - content={"detail": jsonable_encoder(exc.errors())}, - ) diff --git a/env/lib/python3.8/site-packages/fastapi/exceptions.py b/env/lib/python3.8/site-packages/fastapi/exceptions.py deleted file mode 100644 index 8d92311d..00000000 --- a/env/lib/python3.8/site-packages/fastapi/exceptions.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import Any, Dict, Optional, Sequence - -from pydantic import ValidationError, create_model -from pydantic.error_wrappers import ErrorList -from starlette.exceptions import HTTPException as StarletteHTTPException - - -class HTTPException(StarletteHTTPException): - def __init__( - self, - status_code: int, - detail: Any = None, - headers: Optional[Dict[str, Any]] = None, - ) -> None: - super().__init__(status_code=status_code, detail=detail) - self.headers = headers - - -RequestErrorModel = create_model("Request") -WebSocketErrorModel = create_model("WebSocket") - - -class FastAPIError(RuntimeError): - """ - A generic, FastAPI-specific error. - """ - - -class RequestValidationError(ValidationError): - def __init__(self, errors: Sequence[ErrorList], *, body: Any = None) -> None: - self.body = body - super().__init__(errors, RequestErrorModel) - - -class WebSocketRequestValidationError(ValidationError): - def __init__(self, errors: Sequence[ErrorList]) -> None: - super().__init__(errors, WebSocketErrorModel) diff --git a/env/lib/python3.8/site-packages/fastapi/logger.py b/env/lib/python3.8/site-packages/fastapi/logger.py deleted file mode 100644 index 5b2c4ad5..00000000 --- a/env/lib/python3.8/site-packages/fastapi/logger.py +++ /dev/null @@ -1,3 +0,0 @@ -import logging - -logger = logging.getLogger("fastapi") diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/__init__.py b/env/lib/python3.8/site-packages/fastapi/middleware/__init__.py deleted file mode 100644 index 6601b178..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware import Middleware diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index bd10b6b194c5e464d89943396fd4d50084bc099b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmWIL<>g`kf~vMd@j5{IF^Gc(44TX@fuanW zjJLRaGgDG>Qp*#IQvEcUqC|>I5{q(DOG;Apa^Vt1AhT976fpxSF!9S?za+OnzaX-6=Cq2hNKP?exQbDFZ!W8}Z_{_Y_lK6PNg34PQHo5sJ Pr8%i~j6gF#12F>tM36Pl diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/cors.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/cors.cpython-38.pyc deleted file mode 100644 index aff767335d43c8e124537597a239cd594d5e6b6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmWIL<>g`kf~vMd@wPzvF^Gc(44TX@fuanW zjJNol{eyyiGgDG>Qp*#IQvEcUq9lt;5{q(DOG;Apa^Vts$@xXaMIb|0G88cbDKPQN zTE8T>K))cfK({onATc>RHAS~PBQ-Tgx6mNlC?`F~KtC-JXk0<2KEfz{kWqRCmA5!- Sa`RJ4b5iXXf#!V%Vg>+nB{zrw diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/gzip.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/gzip.cpython-38.pyc deleted file mode 100644 index 04de5d1e6375267fbe2e91a7afed5398dad89710..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmWIL<>g`kf~vMd@wPzvF^Gc(44TX@fuanW zjJNpQqcRJ8GgDG>Qp*#IQvEcUq9lt;5{q(DOG;Apa^Vts=~bBpMIb|0G88cbDKPQN zTE8T>K))cfK({onATc>RHAS~PBQ-Tgx6mNlC?`F~KtC-JXk0<2KEfz{kWqRCmA5!- Sa`RJ4b5iXXf#!V%Vg>-288^`Y diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-38.pyc deleted file mode 100644 index ec79e22f850d980ba15c0fa5477f6b042225e170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmWIL<>g`kf~vMd@%}*iF^Gc(44TX@fuanW zjJL!+LP7$9gHls6i&B$Id^1y0a#G6^i&FhGnWB`6OA?E6QcFrw^>X17dKo1p1;s^B z4MiYpRx%VZ11T`^%SFE=w?Mxjvp}~ruOKlwJ2geOJR>zVN4L-*+bAbJ$3Qg`kf~vMd@!mlCF^Gc(44TX@fuanW zjJHHXib{)1Qd2zgi%WbnQ&MtL%M*)I{WO`P6pBj{i*iy+N>cT5;Szc!5ak&_zVN4L-*+bAbJ$3Qg`kf~vMd@wPzvF^Gc(44TX@fuanW zjJNp0gWWxSGgDG>Qp*#IQvEcUq9lt;5{q(DOG;Apa^Vts<;CflMIb|0G88cbDKPQN zTE8T>K))cfK({onATc>RHAS~PBQ-Tgx6mNlC?`F~KtC-JXk0<2KEfz{kWqRCmA5!- Sa`RJ4b5iXXf#!V%Vg>+q**B2@ diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/cors.py b/env/lib/python3.8/site-packages/fastapi/middleware/cors.py deleted file mode 100644 index 4c08a161..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/cors.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.cors import CORSMiddleware # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/gzip.py b/env/lib/python3.8/site-packages/fastapi/middleware/gzip.py deleted file mode 100644 index 08460d07..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/gzip.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.gzip import GZipMiddleware # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/httpsredirect.py b/env/lib/python3.8/site-packages/fastapi/middleware/httpsredirect.py deleted file mode 100644 index 674263af..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/httpsredirect.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/trustedhost.py b/env/lib/python3.8/site-packages/fastapi/middleware/trustedhost.py deleted file mode 100644 index b16aee87..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/trustedhost.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.trustedhost import TrustedHostMiddleware # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/middleware/wsgi.py b/env/lib/python3.8/site-packages/fastapi/middleware/wsgi.py deleted file mode 100644 index bf8d3e66..00000000 --- a/env/lib/python3.8/site-packages/fastapi/middleware/wsgi.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.wsgi import WSGIMiddleware # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/__init__.py b/env/lib/python3.8/site-packages/fastapi/openapi/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index df013fc8d0d77c746cb005219d9bd91066c235b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197 zcmWIL<>g`k0*mQ~;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_kenx(7s(x{5 za#3nYeqO46dS*#{QEEYcv3_Y@rhY+Ua!E#NZepHpacWUnYLR|wUYUMQW|DqEWl2VU zp0S>VesN|=sxDAnc4B&Jv3^=&aY=KnrQ@aaopu0`Ckl>5>1}46S zXP;oNo_GaMPSt~x%y06anaszy(WoP^-phON3h}cP|IGq%0j`b#3^9Xku?jO;HMS;* zS!|ot*bb|+UC;*Gn{2U$kJ?RLxh7Pb4(Z$4^jx3niZ`a(vdImhL|45&9XJ~XGdH}% zw8X5$2Ov2y5PCj1!jVifDYz&UR#D8;P~lO#GTFZ+)NyS;xF1p{xODADedyCZ9s9w+ zwaH(8#KG3!WuKkn>C`yc7w}!l)=$ijLy> ziszV%6<#DyI9nI76sO%DR!PA-&^HffT;XY`iZDyC%(y6HBn2ek_HMS;wX;;R<$|BX MXGocVmeDf40VuU>&;S4c diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/docs.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/docs.cpython-38.pyc deleted file mode 100644 index 396158c83b7016ad224d5cf4378e84b0c05c1f4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5752 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 diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/models.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/models.cpython-38.pyc deleted file mode 100644 index 130976e307ef1e225603605526774ea13b88a5f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14522 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 Tc=oW5ze#CLPQ~-1`P6>{=xlsY diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/openapi/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 6603567d9907e9dfc00d6fb7f7c8076614742d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9034 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 b?-XNCvd2JA<9sE(CyYkv@FDcj{`-Fb_n1(F diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/constants.py b/env/lib/python3.8/site-packages/fastapi/openapi/constants.py deleted file mode 100644 index 3e69e552..00000000 --- a/env/lib/python3.8/site-packages/fastapi/openapi/constants.py +++ /dev/null @@ -1,3 +0,0 @@ -METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"} -STATUS_CODES_WITH_NO_BODY = {100, 101, 102, 103, 204, 304} -REF_PREFIX = "#/components/schemas/" diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/docs.py b/env/lib/python3.8/site-packages/fastapi/openapi/docs.py deleted file mode 100644 index 44c4e69a..00000000 --- a/env/lib/python3.8/site-packages/fastapi/openapi/docs.py +++ /dev/null @@ -1,177 +0,0 @@ -import json -from typing import Optional - -from fastapi.encoders import jsonable_encoder -from starlette.responses import HTMLResponse - - -def get_swagger_ui_html( - *, - openapi_url: str, - title: str, - swagger_js_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-bundle.js", - swagger_css_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css", - swagger_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png", - oauth2_redirect_url: Optional[str] = None, - init_oauth: Optional[dict] = None, -) -> HTMLResponse: - - html = f""" - - - - - - {title} - - -
    -
    - - - - - - """ - return HTMLResponse(html) - - -def get_redoc_html( - *, - openapi_url: str, - title: str, - redoc_js_url: str = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js", - redoc_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png", - with_google_fonts: bool = True, -) -> HTMLResponse: - html = f""" - - - - {title} - - - - """ - if with_google_fonts: - html += """ - - """ - html += f""" - - - - - - - - - - """ - return HTMLResponse(html) - - -def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse: - html = """ - - - - - - - """ - return HTMLResponse(content=html) diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/models.py b/env/lib/python3.8/site-packages/fastapi/openapi/models.py deleted file mode 100644 index 3b716766..00000000 --- a/env/lib/python3.8/site-packages/fastapi/openapi/models.py +++ /dev/null @@ -1,351 +0,0 @@ -from enum import Enum -from typing import Any, Callable, Dict, Iterable, List, Optional, Union - -from fastapi.logger import logger -from pydantic import AnyUrl, BaseModel, Field - -try: - import email_validator - - assert email_validator # make autoflake ignore the unused import - from pydantic import EmailStr -except ImportError: # pragma: no cover - - class EmailStr(str): # type: ignore - @classmethod - def __get_validators__(cls) -> Iterable[Callable]: - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - logger.warning( - "email-validator not installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - -class Contact(BaseModel): - name: Optional[str] = None - url: Optional[AnyUrl] = None - email: Optional[EmailStr] = None - - -class License(BaseModel): - name: str - url: Optional[AnyUrl] = None - - -class Info(BaseModel): - title: str - description: Optional[str] = None - termsOfService: Optional[str] = None - contact: Optional[Contact] = None - license: Optional[License] = None - version: str - - -class ServerVariable(BaseModel): - enum: Optional[List[str]] = None - default: str - description: Optional[str] = None - - -class Server(BaseModel): - url: Union[AnyUrl, str] - description: Optional[str] = None - variables: Optional[Dict[str, ServerVariable]] = None - - -class Reference(BaseModel): - ref: str = Field(..., alias="$ref") - - -class Discriminator(BaseModel): - propertyName: str - mapping: Optional[Dict[str, str]] = None - - -class XML(BaseModel): - name: Optional[str] = None - namespace: Optional[str] = None - prefix: Optional[str] = None - attribute: Optional[bool] = None - wrapped: Optional[bool] = None - - -class ExternalDocumentation(BaseModel): - description: Optional[str] = None - url: AnyUrl - - -class SchemaBase(BaseModel): - ref: Optional[str] = Field(None, alias="$ref") - title: Optional[str] = None - multipleOf: Optional[float] = None - maximum: Optional[float] = None - exclusiveMaximum: Optional[float] = None - minimum: Optional[float] = None - exclusiveMinimum: Optional[float] = None - maxLength: Optional[int] = Field(None, gte=0) - minLength: Optional[int] = Field(None, gte=0) - pattern: Optional[str] = None - maxItems: Optional[int] = Field(None, gte=0) - minItems: Optional[int] = Field(None, gte=0) - uniqueItems: Optional[bool] = None - maxProperties: Optional[int] = Field(None, gte=0) - minProperties: Optional[int] = Field(None, gte=0) - required: Optional[List[str]] = None - enum: Optional[List[Any]] = None - type: Optional[str] = None - allOf: Optional[List[Any]] = None - oneOf: Optional[List[Any]] = None - anyOf: Optional[List[Any]] = None - not_: Optional[Any] = Field(None, alias="not") - items: Optional[Any] = None - properties: Optional[Dict[str, Any]] = None - additionalProperties: Optional[Union[Dict[str, Any], bool]] = None - description: Optional[str] = None - format: Optional[str] = None - default: Optional[Any] = None - nullable: Optional[bool] = None - discriminator: Optional[Discriminator] = None - readOnly: Optional[bool] = None - writeOnly: Optional[bool] = None - xml: Optional[XML] = None - externalDocs: Optional[ExternalDocumentation] = None - example: Optional[Any] = None - deprecated: Optional[bool] = None - - -class Schema(SchemaBase): - allOf: Optional[List[SchemaBase]] = None - oneOf: Optional[List[SchemaBase]] = None - anyOf: Optional[List[SchemaBase]] = None - not_: Optional[SchemaBase] = Field(None, alias="not") - items: Optional[SchemaBase] = None - properties: Optional[Dict[str, SchemaBase]] = None - additionalProperties: Optional[Union[Dict[str, Any], bool]] = None - - -class Example(BaseModel): - summary: Optional[str] = None - description: Optional[str] = None - value: Optional[Any] = None - externalValue: Optional[AnyUrl] = None - - -class ParameterInType(Enum): - query = "query" - header = "header" - path = "path" - cookie = "cookie" - - -class Encoding(BaseModel): - contentType: Optional[str] = None - # Workaround OpenAPI recursive reference, using Any - headers: Optional[Dict[str, Union[Any, Reference]]] = None - style: Optional[str] = None - explode: Optional[bool] = None - allowReserved: Optional[bool] = None - - -class MediaType(BaseModel): - schema_: Optional[Union[Schema, Reference]] = Field(None, alias="schema") - example: Optional[Any] = None - examples: Optional[Dict[str, Union[Example, Reference]]] = None - encoding: Optional[Dict[str, Encoding]] = None - - -class ParameterBase(BaseModel): - description: Optional[str] = None - required: Optional[bool] = None - deprecated: Optional[bool] = None - # Serialization rules for simple scenarios - style: Optional[str] = None - explode: Optional[bool] = None - allowReserved: Optional[bool] = None - schema_: Optional[Union[Schema, Reference]] = Field(None, alias="schema") - example: Optional[Any] = None - examples: Optional[Dict[str, Union[Example, Reference]]] = None - # Serialization rules for more complex scenarios - content: Optional[Dict[str, MediaType]] = None - - -class Parameter(ParameterBase): - name: str - in_: ParameterInType = Field(..., alias="in") - - -class Header(ParameterBase): - pass - - -# Workaround OpenAPI recursive reference -class EncodingWithHeaders(Encoding): - headers: Optional[Dict[str, Union[Header, Reference]]] = None - - -class RequestBody(BaseModel): - description: Optional[str] = None - content: Dict[str, MediaType] - required: Optional[bool] = None - - -class Link(BaseModel): - operationRef: Optional[str] = None - operationId: Optional[str] = None - parameters: Optional[Dict[str, Union[Any, str]]] = None - requestBody: Optional[Union[Any, str]] = None - description: Optional[str] = None - server: Optional[Server] = None - - -class Response(BaseModel): - description: str - headers: Optional[Dict[str, Union[Header, Reference]]] = None - content: Optional[Dict[str, MediaType]] = None - links: Optional[Dict[str, Union[Link, Reference]]] = None - - -class Operation(BaseModel): - tags: Optional[List[str]] = None - summary: Optional[str] = None - description: Optional[str] = None - externalDocs: Optional[ExternalDocumentation] = None - operationId: Optional[str] = None - parameters: Optional[List[Union[Parameter, Reference]]] = None - requestBody: Optional[Union[RequestBody, Reference]] = None - responses: Dict[str, Response] - # Workaround OpenAPI recursive reference - callbacks: Optional[Dict[str, Union[Dict[str, Any], Reference]]] = None - deprecated: Optional[bool] = None - security: Optional[List[Dict[str, List[str]]]] = None - servers: Optional[List[Server]] = None - - -class PathItem(BaseModel): - ref: Optional[str] = Field(None, alias="$ref") - summary: Optional[str] = None - description: Optional[str] = None - get: Optional[Operation] = None - put: Optional[Operation] = None - post: Optional[Operation] = None - delete: Optional[Operation] = None - options: Optional[Operation] = None - head: Optional[Operation] = None - patch: Optional[Operation] = None - trace: Optional[Operation] = None - servers: Optional[List[Server]] = None - parameters: Optional[List[Union[Parameter, Reference]]] = None - - -# Workaround OpenAPI recursive reference -class OperationWithCallbacks(BaseModel): - callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None - - -class SecuritySchemeType(Enum): - apiKey = "apiKey" - http = "http" - oauth2 = "oauth2" - openIdConnect = "openIdConnect" - - -class SecurityBase(BaseModel): - type_: SecuritySchemeType = Field(..., alias="type") - description: Optional[str] = None - - -class APIKeyIn(Enum): - query = "query" - header = "header" - cookie = "cookie" - - -class APIKey(SecurityBase): - type_ = Field(SecuritySchemeType.apiKey, alias="type") - in_: APIKeyIn = Field(..., alias="in") - name: str - - -class HTTPBase(SecurityBase): - type_ = Field(SecuritySchemeType.http, alias="type") - scheme: str - - -class HTTPBearer(HTTPBase): - scheme = "bearer" - bearerFormat: Optional[str] = None - - -class OAuthFlow(BaseModel): - refreshUrl: Optional[str] = None - scopes: Dict[str, str] = {} - - -class OAuthFlowImplicit(OAuthFlow): - authorizationUrl: str - - -class OAuthFlowPassword(OAuthFlow): - tokenUrl: str - - -class OAuthFlowClientCredentials(OAuthFlow): - tokenUrl: str - - -class OAuthFlowAuthorizationCode(OAuthFlow): - authorizationUrl: str - tokenUrl: str - - -class OAuthFlows(BaseModel): - implicit: Optional[OAuthFlowImplicit] = None - password: Optional[OAuthFlowPassword] = None - clientCredentials: Optional[OAuthFlowClientCredentials] = None - authorizationCode: Optional[OAuthFlowAuthorizationCode] = None - - -class OAuth2(SecurityBase): - type_ = Field(SecuritySchemeType.oauth2, alias="type") - flows: OAuthFlows - - -class OpenIdConnect(SecurityBase): - type_ = Field(SecuritySchemeType.openIdConnect, alias="type") - openIdConnectUrl: str - - -SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer] - - -class Components(BaseModel): - schemas: Optional[Dict[str, Union[Schema, Reference]]] = None - responses: Optional[Dict[str, Union[Response, Reference]]] = None - parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None - examples: Optional[Dict[str, Union[Example, Reference]]] = None - requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None - headers: Optional[Dict[str, Union[Header, Reference]]] = None - securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None - links: Optional[Dict[str, Union[Link, Reference]]] = None - callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None - - -class Tag(BaseModel): - name: str - description: Optional[str] = None - externalDocs: Optional[ExternalDocumentation] = None - - -class OpenAPI(BaseModel): - openapi: str - info: Info - servers: Optional[List[Server]] = None - paths: Dict[str, PathItem] - components: Optional[Components] = None - security: Optional[List[Dict[str, List[str]]]] = None - tags: Optional[List[Tag]] = None - externalDocs: Optional[ExternalDocumentation] = None diff --git a/env/lib/python3.8/site-packages/fastapi/openapi/utils.py b/env/lib/python3.8/site-packages/fastapi/openapi/utils.py deleted file mode 100644 index cd1b1baa..00000000 --- a/env/lib/python3.8/site-packages/fastapi/openapi/utils.py +++ /dev/null @@ -1,366 +0,0 @@ -import http.client -from enum import Enum -from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast - -from fastapi import routing -from fastapi.dependencies.models import Dependant -from fastapi.dependencies.utils import get_flat_dependant, get_flat_params -from fastapi.encoders import jsonable_encoder -from fastapi.openapi.constants import ( - METHODS_WITH_BODY, - REF_PREFIX, - STATUS_CODES_WITH_NO_BODY, -) -from fastapi.openapi.models import OpenAPI -from fastapi.params import Body, Param -from fastapi.utils import ( - deep_dict_update, - generate_operation_id_for_path, - get_model_definitions, -) -from pydantic import BaseModel -from pydantic.fields import ModelField -from pydantic.schema import ( - field_schema, - get_flat_models_from_fields, - get_model_name_map, -) -from pydantic.utils import lenient_issubclass -from starlette.responses import JSONResponse -from starlette.routing import BaseRoute -from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY - -validation_error_definition = { - "title": "ValidationError", - "type": "object", - "properties": { - "loc": {"title": "Location", "type": "array", "items": {"type": "string"}}, - "msg": {"title": "Message", "type": "string"}, - "type": {"title": "Error Type", "type": "string"}, - }, - "required": ["loc", "msg", "type"], -} - -validation_error_response_definition = { - "title": "HTTPValidationError", - "type": "object", - "properties": { - "detail": { - "title": "Detail", - "type": "array", - "items": {"$ref": REF_PREFIX + "ValidationError"}, - } - }, -} - -status_code_ranges: Dict[str, str] = { - "1XX": "Information", - "2XX": "Success", - "3XX": "Redirection", - "4XX": "Client Error", - "5XX": "Server Error", - "DEFAULT": "Default Response", -} - - -def get_openapi_security_definitions(flat_dependant: Dependant) -> Tuple[Dict, List]: - security_definitions = {} - operation_security = [] - for security_requirement in flat_dependant.security_requirements: - security_definition = jsonable_encoder( - security_requirement.security_scheme.model, - by_alias=True, - exclude_none=True, - ) - security_name = security_requirement.security_scheme.scheme_name - security_definitions[security_name] = security_definition - operation_security.append({security_name: security_requirement.scopes}) - return security_definitions, operation_security - - -def get_openapi_operation_parameters( - *, - all_route_params: Sequence[ModelField], - model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str], -) -> List[Dict[str, Any]]: - parameters = [] - for param in all_route_params: - field_info = param.field_info - field_info = cast(Param, field_info) - # ignore mypy error until enum schemas are released - parameter = { - "name": param.alias, - "in": field_info.in_.value, - "required": param.required, - "schema": field_schema( - param, model_name_map=model_name_map, ref_prefix=REF_PREFIX # type: ignore - )[0], - } - if field_info.description: - parameter["description"] = field_info.description - if field_info.deprecated: - parameter["deprecated"] = field_info.deprecated - parameters.append(parameter) - return parameters - - -def get_openapi_operation_request_body( - *, - body_field: Optional[ModelField], - model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str], -) -> Optional[Dict]: - if not body_field: - return None - assert isinstance(body_field, ModelField) - # ignore mypy error until enum schemas are released - body_schema, _, _ = field_schema( - body_field, model_name_map=model_name_map, ref_prefix=REF_PREFIX # type: ignore - ) - field_info = cast(Body, body_field.field_info) - request_media_type = field_info.media_type - required = body_field.required - request_body_oai: Dict[str, Any] = {} - if required: - request_body_oai["required"] = required - request_body_oai["content"] = {request_media_type: {"schema": body_schema}} - return request_body_oai - - -def generate_operation_id(*, route: routing.APIRoute, method: str) -> str: - if route.operation_id: - return route.operation_id - path: str = route.path_format - return generate_operation_id_for_path(name=route.name, path=path, method=method) - - -def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str: - if route.summary: - return route.summary - return route.name.replace("_", " ").title() - - -def get_openapi_operation_metadata(*, route: routing.APIRoute, method: str) -> Dict: - operation: Dict[str, Any] = {} - if route.tags: - operation["tags"] = route.tags - operation["summary"] = generate_operation_summary(route=route, method=method) - if route.description: - operation["description"] = route.description - operation["operationId"] = generate_operation_id(route=route, method=method) - if route.deprecated: - operation["deprecated"] = route.deprecated - return operation - - -def get_openapi_path( - *, route: routing.APIRoute, model_name_map: Dict[Type, str] -) -> Tuple[Dict, Dict, Dict]: - path = {} - security_schemes: Dict[str, Any] = {} - definitions: Dict[str, Any] = {} - assert route.methods is not None, "Methods must be a list" - assert route.response_class, "A response class is needed to generate OpenAPI" - route_response_media_type: Optional[str] = route.response_class.media_type - if route.include_in_schema: - for method in route.methods: - operation = get_openapi_operation_metadata(route=route, method=method) - parameters: List[Dict] = [] - flat_dependant = get_flat_dependant(route.dependant, skip_repeats=True) - security_definitions, operation_security = get_openapi_security_definitions( - flat_dependant=flat_dependant - ) - if operation_security: - operation.setdefault("security", []).extend(operation_security) - if security_definitions: - security_schemes.update(security_definitions) - all_route_params = get_flat_params(route.dependant) - operation_parameters = get_openapi_operation_parameters( - all_route_params=all_route_params, model_name_map=model_name_map - ) - parameters.extend(operation_parameters) - if parameters: - operation["parameters"] = list( - {param["name"]: param for param in parameters}.values() - ) - if method in METHODS_WITH_BODY: - request_body_oai = get_openapi_operation_request_body( - body_field=route.body_field, model_name_map=model_name_map - ) - if request_body_oai: - operation["requestBody"] = request_body_oai - if route.callbacks: - callbacks = {} - for callback in route.callbacks: - cb_path, cb_security_schemes, cb_definitions, = get_openapi_path( - route=callback, model_name_map=model_name_map - ) - callbacks[callback.name] = {callback.path: cb_path} - operation["callbacks"] = callbacks - status_code = str(route.status_code) - operation.setdefault("responses", {}).setdefault(status_code, {})[ - "description" - ] = route.response_description - if ( - route_response_media_type - and route.status_code not in STATUS_CODES_WITH_NO_BODY - ): - response_schema = {"type": "string"} - if lenient_issubclass(route.response_class, JSONResponse): - if route.response_field: - response_schema, _, _ = field_schema( - route.response_field, - model_name_map=model_name_map, - ref_prefix=REF_PREFIX, - ) - else: - response_schema = {} - operation.setdefault("responses", {}).setdefault( - status_code, {} - ).setdefault("content", {}).setdefault(route_response_media_type, {})[ - "schema" - ] = response_schema - if route.responses: - operation_responses = operation.setdefault("responses", {}) - for ( - additional_status_code, - additional_response, - ) in route.responses.items(): - process_response = additional_response.copy() - process_response.pop("model", None) - status_code_key = str(additional_status_code).upper() - if status_code_key == "DEFAULT": - status_code_key = "default" - openapi_response = operation_responses.setdefault( - status_code_key, {} - ) - assert isinstance( - process_response, dict - ), "An additional response must be a dict" - field = route.response_fields.get(additional_status_code) - additional_field_schema: Optional[Dict[str, Any]] = None - if field: - additional_field_schema, _, _ = field_schema( - field, model_name_map=model_name_map, ref_prefix=REF_PREFIX - ) - media_type = route_response_media_type or "application/json" - additional_schema = ( - process_response.setdefault("content", {}) - .setdefault(media_type, {}) - .setdefault("schema", {}) - ) - deep_dict_update(additional_schema, additional_field_schema) - status_text: Optional[str] = status_code_ranges.get( - str(additional_status_code).upper() - ) or http.client.responses.get(int(additional_status_code)) - description = ( - process_response.get("description") - or openapi_response.get("description") - or status_text - or "Additional Response" - ) - deep_dict_update(openapi_response, process_response) - openapi_response["description"] = description - http422 = str(HTTP_422_UNPROCESSABLE_ENTITY) - if (all_route_params or route.body_field) and not any( - [ - status in operation["responses"] - for status in [http422, "4XX", "default"] - ] - ): - operation["responses"][http422] = { - "description": "Validation Error", - "content": { - "application/json": { - "schema": {"$ref": REF_PREFIX + "HTTPValidationError"} - } - }, - } - if "ValidationError" not in definitions: - definitions.update( - { - "ValidationError": validation_error_definition, - "HTTPValidationError": validation_error_response_definition, - } - ) - path[method.lower()] = operation - return path, security_schemes, definitions - - -def get_flat_models_from_routes( - routes: Sequence[BaseRoute], -) -> Set[Union[Type[BaseModel], Type[Enum]]]: - body_fields_from_routes: List[ModelField] = [] - responses_from_routes: List[ModelField] = [] - request_fields_from_routes: List[ModelField] = [] - callback_flat_models: Set[Union[Type[BaseModel], Type[Enum]]] = set() - for route in routes: - if getattr(route, "include_in_schema", None) and isinstance( - route, routing.APIRoute - ): - if route.body_field: - assert isinstance( - route.body_field, ModelField - ), "A request body must be a Pydantic Field" - body_fields_from_routes.append(route.body_field) - if route.response_field: - responses_from_routes.append(route.response_field) - if route.response_fields: - responses_from_routes.extend(route.response_fields.values()) - if route.callbacks: - callback_flat_models |= get_flat_models_from_routes(route.callbacks) - params = get_flat_params(route.dependant) - request_fields_from_routes.extend(params) - - flat_models = callback_flat_models | get_flat_models_from_fields( - body_fields_from_routes + responses_from_routes + request_fields_from_routes, - known_models=set(), - ) - return flat_models - - -def get_openapi( - *, - title: str, - version: str, - openapi_version: str = "3.0.2", - description: Optional[str] = None, - routes: Sequence[BaseRoute], - tags: Optional[List[Dict[str, Any]]] = None, - servers: Optional[List[Dict[str, Union[str, Any]]]] = None, -) -> Dict: - info = {"title": title, "version": version} - if description: - info["description"] = description - output: Dict[str, Any] = {"openapi": openapi_version, "info": info} - if servers: - output["servers"] = servers - components: Dict[str, Dict] = {} - paths: Dict[str, Dict] = {} - flat_models = get_flat_models_from_routes(routes) - # ignore mypy error until enum schemas are released - model_name_map = get_model_name_map(flat_models) # type: ignore - # ignore mypy error until enum schemas are released - definitions = get_model_definitions( - flat_models=flat_models, model_name_map=model_name_map # type: ignore - ) - for route in routes: - if isinstance(route, routing.APIRoute): - result = get_openapi_path(route=route, model_name_map=model_name_map) - if result: - path, security_schemes, path_definitions = result - if path: - paths.setdefault(route.path_format, {}).update(path) - if security_schemes: - components.setdefault("securitySchemes", {}).update( - security_schemes - ) - if path_definitions: - definitions.update(path_definitions) - if definitions: - components["schemas"] = {k: definitions[k] for k in sorted(definitions)} - if components: - output["components"] = components - output["paths"] = paths - if tags: - output["tags"] = tags - return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) diff --git a/env/lib/python3.8/site-packages/fastapi/param_functions.py b/env/lib/python3.8/site-packages/fastapi/param_functions.py deleted file mode 100644 index 91620c7c..00000000 --- a/env/lib/python3.8/site-packages/fastapi/param_functions.py +++ /dev/null @@ -1,253 +0,0 @@ -from typing import Any, Callable, Optional, Sequence - -from fastapi import params - - -def Path( # noqa: N802 - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, -) -> Any: - return params.Path( - default=default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -def Query( # noqa: N802 - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, -) -> Any: - return params.Query( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -def Header( # noqa: N802 - default: Any, - *, - alias: Optional[str] = None, - convert_underscores: bool = True, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, -) -> Any: - return params.Header( - default, - alias=alias, - convert_underscores=convert_underscores, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -def Cookie( # noqa: N802 - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, -) -> Any: - return params.Cookie( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -def Body( # noqa: N802 - default: Any, - *, - embed: bool = False, - media_type: str = "application/json", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, -) -> Any: - return params.Body( - default, - embed=embed, - media_type=media_type, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -def Form( # noqa: N802 - default: Any, - *, - media_type: str = "application/x-www-form-urlencoded", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, -) -> Any: - return params.Form( - default, - media_type=media_type, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -def File( # noqa: N802 - default: Any, - *, - media_type: str = "multipart/form-data", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, -) -> Any: - return params.File( - default, - media_type=media_type, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -def Depends( # noqa: N802 - dependency: Optional[Callable] = None, *, use_cache: bool = True -) -> Any: - return params.Depends(dependency=dependency, use_cache=use_cache) - - -def Security( # noqa: N802 - dependency: Optional[Callable] = None, - *, - scopes: Optional[Sequence[str]] = None, - use_cache: bool = True, -) -> Any: - return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache) diff --git a/env/lib/python3.8/site-packages/fastapi/params.py b/env/lib/python3.8/site-packages/fastapi/params.py deleted file mode 100644 index f53e2dba..00000000 --- a/env/lib/python3.8/site-packages/fastapi/params.py +++ /dev/null @@ -1,338 +0,0 @@ -from enum import Enum -from typing import Any, Callable, Optional, Sequence - -from pydantic.fields import FieldInfo - - -class ParamTypes(Enum): - query = "query" - header = "header" - path = "path" - cookie = "cookie" - - -class Param(FieldInfo): - in_: ParamTypes - - def __init__( - self, - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, - ): - self.deprecated = deprecated - super().__init__( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.default})" - - -class Path(Param): - in_ = ParamTypes.path - - def __init__( - self, - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, - ): - self.in_ = self.in_ - super().__init__( - ..., - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -class Query(Param): - in_ = ParamTypes.query - - def __init__( - self, - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, - ): - super().__init__( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -class Header(Param): - in_ = ParamTypes.header - - def __init__( - self, - default: Any, - *, - alias: Optional[str] = None, - convert_underscores: bool = True, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, - ): - self.convert_underscores = convert_underscores - super().__init__( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -class Cookie(Param): - in_ = ParamTypes.cookie - - def __init__( - self, - default: Any, - *, - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - deprecated: Optional[bool] = None, - **extra: Any, - ): - super().__init__( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - deprecated=deprecated, - **extra, - ) - - -class Body(FieldInfo): - def __init__( - self, - default: Any, - *, - embed: bool = False, - media_type: str = "application/json", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, - ): - self.embed = embed - self.media_type = media_type - super().__init__( - default, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.default})" - - -class Form(Body): - def __init__( - self, - default: Any, - *, - media_type: str = "application/x-www-form-urlencoded", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, - ): - super().__init__( - default, - embed=True, - media_type=media_type, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -class File(Form): - def __init__( - self, - default: Any, - *, - media_type: str = "multipart/form-data", - alias: Optional[str] = None, - title: Optional[str] = None, - description: Optional[str] = None, - gt: Optional[float] = None, - ge: Optional[float] = None, - lt: Optional[float] = None, - le: Optional[float] = None, - min_length: Optional[int] = None, - max_length: Optional[int] = None, - regex: Optional[str] = None, - **extra: Any, - ): - super().__init__( - default, - media_type=media_type, - alias=alias, - title=title, - description=description, - gt=gt, - ge=ge, - lt=lt, - le=le, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -class Depends: - def __init__( - self, dependency: Optional[Callable] = None, *, use_cache: bool = True - ): - self.dependency = dependency - self.use_cache = use_cache - - def __repr__(self) -> str: - attr = getattr(self.dependency, "__name__", type(self.dependency).__name__) - cache = "" if self.use_cache else ", use_cache=False" - return f"{self.__class__.__name__}({attr}{cache})" - - -class Security(Depends): - def __init__( - self, - dependency: Optional[Callable] = None, - *, - scopes: Optional[Sequence[str]] = None, - use_cache: bool = True, - ): - super().__init__(dependency=dependency, use_cache=use_cache) - self.scopes = scopes or [] diff --git a/env/lib/python3.8/site-packages/fastapi/py.typed b/env/lib/python3.8/site-packages/fastapi/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/fastapi/requests.py b/env/lib/python3.8/site-packages/fastapi/requests.py deleted file mode 100644 index d16552c0..00000000 --- a/env/lib/python3.8/site-packages/fastapi/requests.py +++ /dev/null @@ -1,2 +0,0 @@ -from starlette.requests import HTTPConnection as HTTPConnection # noqa: F401 -from starlette.requests import Request as Request # noqa: F401 diff --git a/env/lib/python3.8/site-packages/fastapi/responses.py b/env/lib/python3.8/site-packages/fastapi/responses.py deleted file mode 100644 index 0aeff61d..00000000 --- a/env/lib/python3.8/site-packages/fastapi/responses.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Any - -from starlette.responses import FileResponse # noqa -from starlette.responses import HTMLResponse # noqa -from starlette.responses import JSONResponse # noqa -from starlette.responses import PlainTextResponse # noqa -from starlette.responses import RedirectResponse # noqa -from starlette.responses import Response # noqa -from starlette.responses import StreamingResponse # noqa -from starlette.responses import UJSONResponse # noqa - -try: - import orjson -except ImportError: # pragma: nocover - orjson = None # type: ignore - - -class ORJSONResponse(JSONResponse): - media_type = "application/json" - - def render(self, content: Any) -> bytes: - assert orjson is not None, "orjson must be installed to use ORJSONResponse" - return orjson.dumps(content) diff --git a/env/lib/python3.8/site-packages/fastapi/routing.py b/env/lib/python3.8/site-packages/fastapi/routing.py deleted file mode 100644 index e455f81c..00000000 --- a/env/lib/python3.8/site-packages/fastapi/routing.py +++ /dev/null @@ -1,1016 +0,0 @@ -import asyncio -import enum -import inspect -import json -from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Type, Union - -from fastapi import params -from fastapi.dependencies.models import Dependant -from fastapi.dependencies.utils import ( - get_body_field, - get_dependant, - get_parameterless_sub_dependant, - solve_dependencies, -) -from fastapi.encoders import DictIntStrAny, SetIntStr, jsonable_encoder -from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError -from fastapi.openapi.constants import STATUS_CODES_WITH_NO_BODY -from fastapi.utils import ( - create_cloned_field, - create_response_field, - generate_operation_id_for_path, -) -from pydantic import BaseModel -from pydantic.error_wrappers import ErrorWrapper, ValidationError -from pydantic.fields import ModelField -from starlette import routing -from starlette.concurrency import run_in_threadpool -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.responses import JSONResponse, Response -from starlette.routing import Mount # noqa -from starlette.routing import ( - compile_path, - get_name, - request_response, - websocket_session, -) -from starlette.status import WS_1008_POLICY_VIOLATION -from starlette.types import ASGIApp -from starlette.websockets import WebSocket - - -def _prepare_response_content( - res: Any, - *, - exclude_unset: bool, - exclude_defaults: bool = False, - exclude_none: bool = False, -) -> Any: - if isinstance(res, BaseModel): - return res.dict( - by_alias=True, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - elif isinstance(res, list): - return [ - _prepare_response_content( - item, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - for item in res - ] - elif isinstance(res, dict): - return { - k: _prepare_response_content( - v, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - for k, v in res.items() - } - return res - - -async def serialize_response( - *, - field: Optional[ModelField] = None, - response_content: Any, - include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - by_alias: bool = True, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - is_coroutine: bool = True, -) -> Any: - if field: - errors = [] - response_content = _prepare_response_content( - response_content, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - if is_coroutine: - value, errors_ = field.validate(response_content, {}, loc=("response",)) - else: - value, errors_ = await run_in_threadpool( - field.validate, response_content, {}, loc=("response",) - ) - if isinstance(errors_, ErrorWrapper): - errors.append(errors_) - elif isinstance(errors_, list): - errors.extend(errors_) - if errors: - raise ValidationError(errors, field.type_) - return jsonable_encoder( - value, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - else: - return jsonable_encoder(response_content) - - -async def run_endpoint_function( - *, dependant: Dependant, values: Dict[str, Any], is_coroutine: bool -) -> Any: - # Only called by get_request_handler. Has been split into its own function to - # facilitate profiling endpoints, since inner functions are harder to profile. - assert dependant.call is not None, "dependant.call must be a function" - - if is_coroutine: - return await dependant.call(**values) - else: - return await run_in_threadpool(dependant.call, **values) - - -def get_request_handler( - dependant: Dependant, - body_field: Optional[ModelField] = None, - status_code: int = 200, - response_class: Type[Response] = JSONResponse, - response_field: Optional[ModelField] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - dependency_overrides_provider: Optional[Any] = None, -) -> Callable: - assert dependant.call is not None, "dependant.call must be a function" - is_coroutine = asyncio.iscoroutinefunction(dependant.call) - is_body_form = body_field and isinstance(body_field.field_info, params.Form) - - async def app(request: Request) -> Response: - try: - body = None - if body_field: - if is_body_form: - body = await request.form() - else: - body_bytes = await request.body() - if body_bytes: - body = await request.json() - except json.JSONDecodeError as e: - raise RequestValidationError([ErrorWrapper(e, ("body", e.pos))], body=e.doc) - except Exception as e: - raise HTTPException( - status_code=400, detail="There was an error parsing the body" - ) from e - solved_result = await solve_dependencies( - request=request, - dependant=dependant, - body=body, - dependency_overrides_provider=dependency_overrides_provider, - ) - values, errors, background_tasks, sub_response, _ = solved_result - if errors: - raise RequestValidationError(errors, body=body) - else: - raw_response = await run_endpoint_function( - dependant=dependant, values=values, is_coroutine=is_coroutine - ) - - if isinstance(raw_response, Response): - if raw_response.background is None: - raw_response.background = background_tasks - return raw_response - response_data = await serialize_response( - field=response_field, - response_content=raw_response, - include=response_model_include, - exclude=response_model_exclude, - by_alias=response_model_by_alias, - exclude_unset=response_model_exclude_unset, - exclude_defaults=response_model_exclude_defaults, - exclude_none=response_model_exclude_none, - is_coroutine=is_coroutine, - ) - response = response_class( - content=response_data, - status_code=status_code, - background=background_tasks, - ) - response.headers.raw.extend(sub_response.headers.raw) - if sub_response.status_code: - response.status_code = sub_response.status_code - return response - - return app - - -def get_websocket_app( - dependant: Dependant, dependency_overrides_provider: Optional[Any] = None -) -> Callable: - async def app(websocket: WebSocket) -> None: - solved_result = await solve_dependencies( - request=websocket, - dependant=dependant, - dependency_overrides_provider=dependency_overrides_provider, - ) - values, errors, _, _2, _3 = solved_result - if errors: - await websocket.close(code=WS_1008_POLICY_VIOLATION) - raise WebSocketRequestValidationError(errors) - assert dependant.call is not None, "dependant.call must be a function" - await dependant.call(**values) - - return app - - -class APIWebSocketRoute(routing.WebSocketRoute): - def __init__( - self, - path: str, - endpoint: Callable, - *, - name: Optional[str] = None, - dependency_overrides_provider: Optional[Any] = None, - ) -> None: - self.path = path - self.endpoint = endpoint - self.name = get_name(endpoint) if name is None else name - self.dependant = get_dependant(path=path, call=self.endpoint) - self.app = websocket_session( - get_websocket_app( - dependant=self.dependant, - dependency_overrides_provider=dependency_overrides_provider, - ) - ) - self.path_regex, self.path_format, self.param_convertors = compile_path(path) - - -class APIRoute(routing.Route): - def __init__( - self, - path: str, - endpoint: Callable, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - name: Optional[str] = None, - methods: Optional[Union[Set[str], List[str]]] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - dependency_overrides_provider: Optional[Any] = None, - callbacks: Optional[List["APIRoute"]] = None, - ) -> None: - # normalise enums e.g. http.HTTPStatus - if isinstance(status_code, enum.IntEnum): - status_code = int(status_code) - self.path = path - self.endpoint = endpoint - self.name = get_name(endpoint) if name is None else name - self.path_regex, self.path_format, self.param_convertors = compile_path(path) - if methods is None: - methods = ["GET"] - self.methods = set([method.upper() for method in methods]) - self.unique_id = generate_operation_id_for_path( - name=self.name, path=self.path_format, method=list(methods)[0] - ) - self.response_model = response_model - if self.response_model: - assert ( - status_code not in STATUS_CODES_WITH_NO_BODY - ), f"Status code {status_code} must not have a response body" - response_name = "Response_" + self.unique_id - self.response_field = create_response_field( - name=response_name, type_=self.response_model - ) - # Create a clone of the field, so that a Pydantic submodel is not returned - # as is just because it's an instance of a subclass of a more limited class - # e.g. UserInDB (containing hashed_password) could be a subclass of User - # that doesn't have the hashed_password. But because it's a subclass, it - # would pass the validation and be returned as is. - # By being a new field, no inheritance will be passed as is. A new model - # will be always created. - self.secure_cloned_response_field: Optional[ - ModelField - ] = create_cloned_field(self.response_field) - else: - self.response_field = None # type: ignore - self.secure_cloned_response_field = None - self.status_code = status_code - self.tags = tags or [] - if dependencies: - self.dependencies = list(dependencies) - else: - self.dependencies = [] - self.summary = summary - self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "") - # if a "form feed" character (page break) is found in the description text, - # truncate description text to the content preceding the first "form feed" - self.description = self.description.split("\f")[0] - self.response_description = response_description - self.responses = responses or {} - response_fields = {} - for additional_status_code, response in self.responses.items(): - assert isinstance(response, dict), "An additional response must be a dict" - model = response.get("model") - if model: - assert ( - additional_status_code not in STATUS_CODES_WITH_NO_BODY - ), f"Status code {additional_status_code} must not have a response body" - response_name = f"Response_{additional_status_code}_{self.unique_id}" - response_field = create_response_field(name=response_name, type_=model) - response_fields[additional_status_code] = response_field - if response_fields: - self.response_fields: Dict[Union[int, str], ModelField] = response_fields - else: - self.response_fields = {} - self.deprecated = deprecated - self.operation_id = operation_id - self.response_model_include = response_model_include - self.response_model_exclude = response_model_exclude - self.response_model_by_alias = response_model_by_alias - self.response_model_exclude_unset = response_model_exclude_unset - self.response_model_exclude_defaults = response_model_exclude_defaults - self.response_model_exclude_none = response_model_exclude_none - self.include_in_schema = include_in_schema - self.response_class = response_class - - assert callable(endpoint), "An endpoint must be a callable" - self.dependant = get_dependant(path=self.path_format, call=self.endpoint) - for depends in self.dependencies[::-1]: - self.dependant.dependencies.insert( - 0, - get_parameterless_sub_dependant(depends=depends, path=self.path_format), - ) - self.body_field = get_body_field(dependant=self.dependant, name=self.unique_id) - self.dependency_overrides_provider = dependency_overrides_provider - self.callbacks = callbacks - self.app = request_response(self.get_route_handler()) - - def get_route_handler(self) -> Callable: - return get_request_handler( - dependant=self.dependant, - body_field=self.body_field, - status_code=self.status_code, - response_class=self.response_class or JSONResponse, - response_field=self.secure_cloned_response_field, - response_model_include=self.response_model_include, - response_model_exclude=self.response_model_exclude, - response_model_by_alias=self.response_model_by_alias, - response_model_exclude_unset=self.response_model_exclude_unset, - response_model_exclude_defaults=self.response_model_exclude_defaults, - response_model_exclude_none=self.response_model_exclude_none, - dependency_overrides_provider=self.dependency_overrides_provider, - ) - - -class APIRouter(routing.Router): - def __init__( - self, - routes: Optional[List[routing.BaseRoute]] = None, - redirect_slashes: bool = True, - default: Optional[ASGIApp] = None, - dependency_overrides_provider: Optional[Any] = None, - route_class: Type[APIRoute] = APIRoute, - default_response_class: Optional[Type[Response]] = None, - on_startup: Optional[Sequence[Callable]] = None, - on_shutdown: Optional[Sequence[Callable]] = None, - ) -> None: - super().__init__( - routes=routes, - redirect_slashes=redirect_slashes, - default=default, - on_startup=on_startup, - on_shutdown=on_shutdown, - ) - self.dependency_overrides_provider = dependency_overrides_provider - self.route_class = route_class - self.default_response_class = default_response_class - - def add_api_route( - self, - path: str, - endpoint: Callable, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - methods: Optional[Union[Set[str], List[str]]] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - route_class_override: Optional[Type[APIRoute]] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> None: - route_class = route_class_override or self.route_class - route = route_class( - path, - endpoint=endpoint, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - dependency_overrides_provider=self.dependency_overrides_provider, - callbacks=callbacks, - ) - self.routes.append(route) - - def api_route( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - methods: Optional[List[str]] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - def decorator(func: Callable) -> Callable: - self.add_api_route( - path, - func, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - return func - - return decorator - - def add_api_websocket_route( - self, path: str, endpoint: Callable, name: Optional[str] = None - ) -> None: - route = APIWebSocketRoute( - path, - endpoint=endpoint, - name=name, - dependency_overrides_provider=self.dependency_overrides_provider, - ) - self.routes.append(route) - - def websocket(self, path: str, name: Optional[str] = None) -> Callable: - def decorator(func: Callable) -> Callable: - self.add_api_websocket_route(path, func, name=name) - return func - - return decorator - - def include_router( - self, - router: "APIRouter", - *, - prefix: str = "", - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - default_response_class: Optional[Type[Response]] = None, - ) -> None: - if prefix: - assert prefix.startswith("/"), "A path prefix must start with '/'" - assert not prefix.endswith( - "/" - ), "A path prefix must not end with '/', as the routes will start with '/'" - else: - for r in router.routes: - path = getattr(r, "path") - name = getattr(r, "name", "unknown") - if path is not None and not path: - raise Exception( - f"Prefix and path cannot be both empty (path operation: {name})" - ) - if responses is None: - responses = {} - for route in router.routes: - if isinstance(route, APIRoute): - combined_responses = {**responses, **route.responses} - self.add_api_route( - prefix + route.path, - route.endpoint, - response_model=route.response_model, - status_code=route.status_code, - tags=(route.tags or []) + (tags or []), - dependencies=list(dependencies or []) - + list(route.dependencies or []), - summary=route.summary, - description=route.description, - response_description=route.response_description, - responses=combined_responses, - deprecated=route.deprecated, - methods=route.methods, - operation_id=route.operation_id, - response_model_include=route.response_model_include, - response_model_exclude=route.response_model_exclude, - response_model_by_alias=route.response_model_by_alias, - response_model_exclude_unset=route.response_model_exclude_unset, - response_model_exclude_defaults=route.response_model_exclude_defaults, - response_model_exclude_none=route.response_model_exclude_none, - include_in_schema=route.include_in_schema, - response_class=route.response_class or default_response_class, - name=route.name, - route_class_override=type(route), - callbacks=route.callbacks, - ) - elif isinstance(route, routing.Route): - self.add_route( - prefix + route.path, - route.endpoint, - methods=list(route.methods or []), - include_in_schema=route.include_in_schema, - name=route.name, - ) - elif isinstance(route, APIWebSocketRoute): - self.add_api_websocket_route( - prefix + route.path, route.endpoint, name=route.name - ) - elif isinstance(route, routing.WebSocketRoute): - self.add_websocket_route( - prefix + route.path, route.endpoint, name=route.name - ) - for handler in router.on_startup: - self.add_event_handler("startup", handler) - for handler in router.on_shutdown: - self.add_event_handler("shutdown", handler) - - def get( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["GET"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def put( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["PUT"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def post( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["POST"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def delete( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["DELETE"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def options( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["OPTIONS"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def head( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["HEAD"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def patch( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["PATCH"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) - - def trace( - self, - path: str, - *, - response_model: Optional[Type[Any]] = None, - status_code: int = 200, - tags: Optional[List[str]] = None, - dependencies: Optional[Sequence[params.Depends]] = None, - summary: Optional[str] = None, - description: Optional[str] = None, - response_description: str = "Successful Response", - responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, - deprecated: Optional[bool] = None, - operation_id: Optional[str] = None, - response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: Optional[Type[Response]] = None, - name: Optional[str] = None, - callbacks: Optional[List[APIRoute]] = None, - ) -> Callable: - - return self.api_route( - path=path, - response_model=response_model, - status_code=status_code, - tags=tags or [], - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses or {}, - deprecated=deprecated, - methods=["TRACE"], - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class or self.default_response_class, - name=name, - callbacks=callbacks, - ) diff --git a/env/lib/python3.8/site-packages/fastapi/security/__init__.py b/env/lib/python3.8/site-packages/fastapi/security/__init__.py deleted file mode 100644 index ad727742..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -from .api_key import APIKeyCookie, APIKeyHeader, APIKeyQuery -from .http import ( - HTTPAuthorizationCredentials, - HTTPBasic, - HTTPBasicCredentials, - HTTPBearer, - HTTPDigest, -) -from .oauth2 import ( - OAuth2, - OAuth2AuthorizationCodeBearer, - OAuth2PasswordBearer, - OAuth2PasswordRequestForm, - OAuth2PasswordRequestFormStrict, - SecurityScopes, -) -from .open_id_connect_url import OpenIdConnect diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index a1e5523052ccc3a86a1961e4fe9eea0e12db076b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmZ{i&2G~`5XbF&*!gl2(p->=;OaxW620_*s6%q}kT=rrXduUei?wZ|ok$Dl` z0EyS&G4{%dSK!1>0;oN(l7F6=|9HmZ@!KRB1pXX<`JR0ZgWv}`cTdYZr~WeUJc^(Q z%Rq!Q6fN2kZQ2eo)+#%qOS>YXk%(z5dbB6{w7=EbkqEBs39YIu;W;5mP$d z>Yeg|n9-THyQ?6Le)@L^(zY9&EiYd}vruZo;jecAtN`tXJMDE1x=Fik|Kj?3c~;xC z()=^CT*-xo0;J`vG_H^8IWs(W^MB^uguylnO#8}P`#HY>W7Eh*S6KC_d$haXZ=nh} z-#s+n$xCL;C#8!&(TDe=Z{TC?tG-ZLxX1sMR#x-ey73C~T65d1a#evzLzi4tATNuB zk`i+JD&3mg!ImhT#7wJ!D4E8hY=!z{$F4OuGz#6YgWDhcF<+e|~H45=k270c}!1d|5_^et!t z@|KkRJ*gVMD|vKyOboYh;PW=je{%AH8SAIQg4^jymT~DzW`|Ydde4L^>Jm=y2QfI> KJlv0;^nL>$2+$e; diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/api_key.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/api_key.cpython-38.pyc deleted file mode 100644 index c0bd5711adf7c466071fe8a8ace7b75ea63b4adf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2684 zcmcgu&2Jk;6rY)0@2;J7;)JB4P*N^WVwWiPAE&Lml9Kirvh zg^RgBt{`r`2vHoBG8GAD4%*iPNd3p_KfrS+^4 zG|bpZ7cxKaDfx>;dXq1LzG(CoU)mt; z)?ctI(x%#bFesBEkJ2{N&KD2w-4`S6RsZ*Lu=^V#9?GN~-Hem~y?J+Y^WmLuV__bH z3HOnBJQS*g;R@QqPp)1IzkKlM=Dpju@AP5}Gv6pE>(G@CLXd!R5-?6-OH4PaxEQI| zwzL<9d6bDT)QvFA3O-D6?1$mwVU$*u36V|kW5nP6?rxEZt`e~nWs!^SPEv+a3<}j9 z=1F%D#pSNZqWp>y@`;dLkw59C$yRqTDtC+gTIYIKC8f9m>-M4@p}O0VDx*Py4h;fb zP{KVi>I_B_Do(Keih=N`(O<~52DWuvbOXdJSI)R~z=S1iVVx(U#_a=(*SNC}6cBDT z%iROUJzn3p1J9t-&Y-nCVjhK1I-y*AYD#2$i(Vt zmgI63o^E>*y-IYeYd{4#(lw}-NOe67<1|t#3?*VU+t0+-wi4;KaWI>n)lx2^Hy}Wg zLk+_v(3As$SQqFbeY!daMQ6GQ5OHP2MeP6shBA+_I@31I{STN>S3!(vpZp4W_F3Qh zjegI@Onrpe%FAV~bU0w~6Z?VYHfB6#ChMomy`sDbQ16PoOyZ~%9C*6`JSm4Nj3I07 za8X7{+IF>Xzz7GCj54LI9Z|~HA#9a2mPKMp(gQKEf3(`&x71>YYMk1o9m2fIu~S&ELBe)1@DYU`Dm>G0A~=KR#HnW4HC t%mHsc5X>Pdk?0aPJNLdFy(HTEy!z6)fmgNx&Sx#^S3j#|w^m!L{{nj_CVKz? diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/base.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/base.cpython-38.pyc deleted file mode 100644 index 4ae1f568288fab0911cca05ebfc1762fea74c80a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 484 zcmY*Vu};G<5VeyOMQtj?!pNSX@xaodLWqTlE>)KI?-01F!;jOXiU-W!|xJ&*7`K0DGi-@9{1-zGlgzJ;cO8su;JdM Xze@i!n+$t>I{UWaih5G-T^4@- diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/http.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/http.cpython-38.pyc deleted file mode 100644 index b6ff2ebdf13ca63e3cb2cb5a076e62470948ad4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4550 zcmcgvOK%*<5uTp+E_cc0@+H}dLrad4O`=`fQUoEP9oZrkDM40&Oh(Q?$auKjB8Qrt zS@-nHCb2w35|ES5IYa>@Aea3UIV3m#gt__>{{WpX8Ew-uDQ`wr+xBeA zTanXty#nQJ$QQjS$~#f1UG~b9ccba{j5kC1LR4wbdb5--M%DJ5H%IxYXuiGREwmTC zMW+2y<0W2xr17$teQ0<~P@d*9P@bXkDJWO?ER<(O8QNVaSNR;2=Y$L8(@>u03s7F5 zauLdld%U$5q9v#b z8?oY}AjOVF%8Nh>38m76tL%S zU{ajPxg|d9id5C~YyrphFTV4xztQ|~WBvNgTQ|J5)vP+GzTjWGdF!JatE+3x7H(kj zF`#e-Qu+o6p?QpJp1z?8LztYc~$(wyEbA2BxeLpMuemmja2=gW1|EwECgBBxIGMn-JAdVA7drp17uSvjME)KRD z+euqAQqht^C9!C1h02$rlcbGq95y;ZOM#Ap_&luPzK{(O-)}_WW}~wUii|JRFE`Rq ziSy9!Ua%$7#@!%QK_|okN%@U!r8@P_t}MfpGpGr~c9FS^YW_!sok4|tIC-X%inH_c z&8A>)Lv1!?Ww`gT7UUAvodPirX}m(Ld0~YXR9?YuAAlGhDQ8^g#uFV6Rv4!>VR7?` z!7Xk-0$vISYTeTscb@3n<%LJ4S0Ka}C63ly@9Wvr0E~3dMZjs|3n>#>GvsOLBhR4t z9*7nLfe&H}m5JZ0kkYq6D6Pjhd(3*8&w6@iv8V0mI|h`@9!iUAfHb|?XEbWx&KWfV zer5rZM3fbLzZC)4d|%GOsN>lIrDiIkyGIsvM3)H8Fa{*~ui?UM5Sme9(`;{c0C7h^Zt3{L;6V-HHvb7Jy$+(scC@Fk$!Ba|S9(u>$nNO-#=hCpZ3WzY%Wv~Mtwb30B*15WX`q-xR7aPfRT|dRMJsNT(>NtKq&Psc@Fb$gUHG_&Bzpu zM>|H7tsshg|4sNSMSP+r@wJ)GbWQ({Ynq4kn)k02^P{W6A94-_{wxtKnYo!Hkwm;m zbVRf|`5xv*mLbm(G4KQsgEYIVdbylC~iTIL(hmPt57{bl$T zOAE+jaFbgDx)?+k8|dP2cSM&$Rv1~x<~lF~Ns(Dn1X252xbY+CslbtPeZUQNh#NX` zgBW5HLyTr-Z3b!Bl4!VVj$DS1#3PVrQH)9PQ!FAcYi54BMAT93ghEM|sPlIrr3ezu zK~C6gk6a0mFl>!zA%6hvhlnr*6?j@igfAg;A`uY$?;-G!27l4G`Bx)k`&R5iorO6f zhTXHc^Vrz8fjFP^jHmW9jl1^@Dd8_i#?+^f_ZiY>ud3Xh`H(#=@FLL9xvj;^rlyK& zN|koXca3{R`8THF+p{0A-)ph{iPm$TPV=c}?2fVT?icopy+ZnTY*jNow^!sPqGGuz ze+WC;tK7bQ`#f@TNWi@^sb!hY`2Dj7?5t-|&B56l@%6y2eXXlEzwA!Js`VK z{9O=r#Tr`dthy10Sh-3~d7Zl%#x!GQBMA9ygViJk}KBV*_h}^o^Y+iTK zzTo?B+p6T&hDxpt>}OTB$cn7OOn49D_ayU!mM6DC7ce)rJ{TIDY<+N1??6h?G`S|N z=o{0paYf&h%4C1A&;P^zNc3cAd9u#Z zOnBT;Xi9-8gsHFKY3VYx8bVC3n(Oj)7;uDbG<>)85x*0?G6}x6LEF&(SAu;K;{?Z@+?uKjO&f&|G%LCIDe=?REJJ_yC*W;(O`hz@w?% zP8e_Hfns%VpR0pM$?x1L1-04Yup#M)7%qHux;La03Fg5Po|e3Z!!Hc`4ljjuoKHH? z=8eV~wRKe(rR03!zPrlr*FHsc1djJ3c diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/oauth2.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/oauth2.cpython-38.pyc deleted file mode 100644 index 454977a119d6e16e347a04274acd4af01019c41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7541 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 GU-~!p_KAi7 diff --git a/env/lib/python3.8/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-38.pyc b/env/lib/python3.8/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-38.pyc deleted file mode 100644 index 36ea4b8373ca8fb2fba0ae27f5f585233fe632ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1343 zcmZuxO^+Nk5VhSsJw3BCVY9$WhyxsQpd~Vm6b?C{DC7gkfmxJnE-fUhw_Vxk#oaxz z-79uATwt#`bJ+tN`5W*reC5PnAP1=O?64CFkNmp)RjzvVJkO`oF~fHE=ilWAF=Kzy zV7uWQyN}&|i=dd|nl-%OoNS>*6BTi=BRy!6A_;b^hfP|f!5-*QGcLx#PV`PQDJGnK z$<$D#7fhv){1g?D8a-p#_%FPHW!$F+OILSosnMPuETMg(9(HXDmBWe2GpKq~yR!$S z1={e{;o&!rzpo&i!HMBhc-e!cy?eAKKmFv6{Nmv0gC~z3J)T!|$95aw;68SH4*^)g z6)S||N~q{kKm;*F?=cvt_%c!hm0VzsFkH{7;iXWi8ePOisyJm}B6Ko8%!J>u)dCuj zZP|bym%ZyG7}J?7^1I!3O3#fpDV{PTgo-0jBR|AEeIH`Cw-6j#am8Qp6_b1=misGq zB2FS4#Vf*rVi<#%XWURpv&8ScLEhJ$0__J)_>82ibZM=WK9wO#DX-(mVjo-3FM^}% z>ED>yMbCeq=8LX@+(Ko*buHw_wUY*xoz45U&X;B7F!{2*ZNZ#^$)P>Xb$ygC&)lMG z@67JzwsvqE_kC9$gUw%*)|Jbe9EQ^7#E`6&tkz|hz0tGf8AV#Rc$M5CN)iM%obVg` zeE*F^XPa$UhoM=k!6z7MZ`w-GsjIeO`41f1j}cbE}IWWa{&h1bcpS-nkF4)(dD|U6l@0P=YI6Z!s4IK2hMxT4w`4 zTtKP7SRWmO3&l4iMKeUmBJ&p6ZzK3AIsEUAP=Gbuq*bJ(Dz%n!A4hf%f$<5CdBO!3 zO#G9^@&C}XK9Y^h4e~LT5=GH#Kru|DeA$Qj4bl7E>jkv1I)V1BR6=HJfJ5cOv_3L%kbp+G6wB5^^J0wE;&G=U~UTA6r~wb-9*Z=^*@#~o-WpyV1H z!z~q8pkf>(6vldEkLL5<_;xVp5wywkN7|!=e1>4(A`Gq&_6(gOisq!Cb4m#?pa`~P z$3(FgrnripqB&Rbj3k{etR@Nd@l8|bkT8ED8<$l^KT4;oGR;6LFzH(64fu`$*O+pF z{C^gBIpP{&hv+uMb`_oB{fc~V^p0=omTmclZupWRC!Zn>F)`MD(;;#n)Y3Q|=#t2U zS-xWz85H1Y>SIjG;+>eoP@jpcDnM9Rpp>cvvC=LzP*+wor53eZIBb;V$bwme5m2s0 zuJ1+N;!@@Lcp|KJFv7YAxdJPe(mGk|Ft9P&wW4u4x8u6?rz>#j|G)SZmF@(EwQUz2 up%I=VY6ke8CXw&Bw$|m!FpNF7&g?Qf`FpM(vfYcKQcVt*;X`d`=<^?~XMSV= diff --git a/env/lib/python3.8/site-packages/fastapi/security/api_key.py b/env/lib/python3.8/site-packages/fastapi/security/api_key.py deleted file mode 100644 index e4dacb38..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/api_key.py +++ /dev/null @@ -1,71 +0,0 @@ -from typing import Optional - -from fastapi.openapi.models import APIKey, APIKeyIn -from fastapi.security.base import SecurityBase -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.status import HTTP_403_FORBIDDEN - - -class APIKeyBase(SecurityBase): - pass - - -class APIKeyQuery(APIKeyBase): - def __init__( - self, *, name: str, scheme_name: Optional[str] = None, auto_error: bool = True - ): - self.model: APIKey = APIKey(**{"in": APIKeyIn.query}, name=name) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__(self, request: Request) -> Optional[str]: - api_key: str = request.query_params.get(self.model.name) - if not api_key: - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return api_key - - -class APIKeyHeader(APIKeyBase): - def __init__( - self, *, name: str, scheme_name: Optional[str] = None, auto_error: bool = True - ): - self.model: APIKey = APIKey(**{"in": APIKeyIn.header}, name=name) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__(self, request: Request) -> Optional[str]: - api_key: str = request.headers.get(self.model.name) - if not api_key: - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return api_key - - -class APIKeyCookie(APIKeyBase): - def __init__( - self, *, name: str, scheme_name: Optional[str] = None, auto_error: bool = True - ): - self.model: APIKey = APIKey(**{"in": APIKeyIn.cookie}, name=name) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__(self, request: Request) -> Optional[str]: - api_key = request.cookies.get(self.model.name) - if not api_key: - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return api_key diff --git a/env/lib/python3.8/site-packages/fastapi/security/base.py b/env/lib/python3.8/site-packages/fastapi/security/base.py deleted file mode 100644 index c43555de..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/base.py +++ /dev/null @@ -1,6 +0,0 @@ -from fastapi.openapi.models import SecurityBase as SecurityBaseModel - - -class SecurityBase: - model: SecurityBaseModel - scheme_name: str diff --git a/env/lib/python3.8/site-packages/fastapi/security/http.py b/env/lib/python3.8/site-packages/fastapi/security/http.py deleted file mode 100644 index 3258bd05..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/http.py +++ /dev/null @@ -1,152 +0,0 @@ -import binascii -from base64 import b64decode -from typing import Optional - -from fastapi.exceptions import HTTPException -from fastapi.openapi.models import HTTPBase as HTTPBaseModel -from fastapi.openapi.models import HTTPBearer as HTTPBearerModel -from fastapi.security.base import SecurityBase -from fastapi.security.utils import get_authorization_scheme_param -from pydantic import BaseModel -from starlette.requests import Request -from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN - - -class HTTPBasicCredentials(BaseModel): - username: str - password: str - - -class HTTPAuthorizationCredentials(BaseModel): - scheme: str - credentials: str - - -class HTTPBase(SecurityBase): - def __init__( - self, *, scheme: str, scheme_name: Optional[str] = None, auto_error: bool = True - ): - self.model = HTTPBaseModel(scheme=scheme) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__( - self, request: Request - ) -> Optional[HTTPAuthorizationCredentials]: - authorization: str = request.headers.get("Authorization") - scheme, credentials = get_authorization_scheme_param(authorization) - if not (authorization and scheme and credentials): - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) - - -class HTTPBasic(HTTPBase): - def __init__( - self, - *, - scheme_name: Optional[str] = None, - realm: Optional[str] = None, - auto_error: bool = True, - ): - self.model = HTTPBaseModel(scheme="basic") - self.scheme_name = scheme_name or self.__class__.__name__ - self.realm = realm - self.auto_error = auto_error - - async def __call__( # type: ignore - self, request: Request - ) -> Optional[HTTPBasicCredentials]: - authorization: str = request.headers.get("Authorization") - scheme, param = get_authorization_scheme_param(authorization) - if self.realm: - unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'} - else: - unauthorized_headers = {"WWW-Authenticate": "Basic"} - invalid_user_credentials_exc = HTTPException( - status_code=HTTP_401_UNAUTHORIZED, - detail="Invalid authentication credentials", - headers=unauthorized_headers, - ) - if not authorization or scheme.lower() != "basic": - if self.auto_error: - raise HTTPException( - status_code=HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - headers=unauthorized_headers, - ) - else: - return None - try: - data = b64decode(param).decode("ascii") - except (ValueError, UnicodeDecodeError, binascii.Error): - raise invalid_user_credentials_exc - username, separator, password = data.partition(":") - if not separator: - raise invalid_user_credentials_exc - return HTTPBasicCredentials(username=username, password=password) - - -class HTTPBearer(HTTPBase): - def __init__( - self, - *, - bearerFormat: Optional[str] = None, - scheme_name: Optional[str] = None, - auto_error: bool = True, - ): - self.model = HTTPBearerModel(bearerFormat=bearerFormat) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__( - self, request: Request - ) -> Optional[HTTPAuthorizationCredentials]: - authorization: str = request.headers.get("Authorization") - scheme, credentials = get_authorization_scheme_param(authorization) - if not (authorization and scheme and credentials): - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - if scheme.lower() != "bearer": - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, - detail="Invalid authentication credentials", - ) - else: - return None - return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) - - -class HTTPDigest(HTTPBase): - def __init__(self, *, scheme_name: Optional[str] = None, auto_error: bool = True): - self.model = HTTPBaseModel(scheme="digest") - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__( - self, request: Request - ) -> Optional[HTTPAuthorizationCredentials]: - authorization: str = request.headers.get("Authorization") - scheme, credentials = get_authorization_scheme_param(authorization) - if not (authorization and scheme and credentials): - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - if scheme.lower() != "digest": - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, - detail="Invalid authentication credentials", - ) - return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) diff --git a/env/lib/python3.8/site-packages/fastapi/security/oauth2.py b/env/lib/python3.8/site-packages/fastapi/security/oauth2.py deleted file mode 100644 index 0d1a5f12..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/oauth2.py +++ /dev/null @@ -1,207 +0,0 @@ -from typing import List, Optional - -from fastapi.exceptions import HTTPException -from fastapi.openapi.models import OAuth2 as OAuth2Model -from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel -from fastapi.param_functions import Form -from fastapi.security.base import SecurityBase -from fastapi.security.utils import get_authorization_scheme_param -from starlette.requests import Request -from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN - - -class OAuth2PasswordRequestForm: - """ - This is a dependency class, use it like: - - @app.post("/login") - def login(form_data: OAuth2PasswordRequestForm = Depends()): - data = form_data.parse() - print(data.username) - print(data.password) - for scope in data.scopes: - print(scope) - if data.client_id: - print(data.client_id) - if data.client_secret: - print(data.client_secret) - return data - - - It creates the following Form request parameters in your endpoint: - - grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password". - Nevertheless, this dependency class is permissive and allows not passing it. If you want to enforce it, - use instead the OAuth2PasswordRequestFormStrict dependency. - username: username string. The OAuth2 spec requires the exact field name "username". - password: password string. The OAuth2 spec requires the exact field name "password". - scope: Optional string. Several scopes (each one a string) separated by spaces. E.g. - "items:read items:write users:read profile openid" - client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any) - using HTTP Basic auth, as: client_id:client_secret - client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any) - using HTTP Basic auth, as: client_id:client_secret - """ - - def __init__( - self, - grant_type: str = Form(None, regex="password"), - username: str = Form(...), - password: str = Form(...), - scope: str = Form(""), - client_id: Optional[str] = Form(None), - client_secret: Optional[str] = Form(None), - ): - self.grant_type = grant_type - self.username = username - self.password = password - self.scopes = scope.split() - self.client_id = client_id - self.client_secret = client_secret - - -class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): - """ - This is a dependency class, use it like: - - @app.post("/login") - def login(form_data: OAuth2PasswordRequestFormStrict = Depends()): - data = form_data.parse() - print(data.username) - print(data.password) - for scope in data.scopes: - print(scope) - if data.client_id: - print(data.client_id) - if data.client_secret: - print(data.client_secret) - return data - - - It creates the following Form request parameters in your endpoint: - - grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password". - This dependency is strict about it. If you want to be permissive, use instead the - OAuth2PasswordRequestForm dependency class. - username: username string. The OAuth2 spec requires the exact field name "username". - password: password string. The OAuth2 spec requires the exact field name "password". - scope: Optional string. Several scopes (each one a string) separated by spaces. E.g. - "items:read items:write users:read profile openid" - client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any) - using HTTP Basic auth, as: client_id:client_secret - client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any) - using HTTP Basic auth, as: client_id:client_secret - """ - - def __init__( - self, - grant_type: str = Form(..., regex="password"), - username: str = Form(...), - password: str = Form(...), - scope: str = Form(""), - client_id: Optional[str] = Form(None), - client_secret: Optional[str] = Form(None), - ): - super().__init__( - grant_type=grant_type, - username=username, - password=password, - scope=scope, - client_id=client_id, - client_secret=client_secret, - ) - - -class OAuth2(SecurityBase): - def __init__( - self, - *, - flows: OAuthFlowsModel = OAuthFlowsModel(), - scheme_name: Optional[str] = None, - auto_error: Optional[bool] = True - ): - self.model = OAuth2Model(flows=flows) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__(self, request: Request) -> Optional[str]: - authorization: str = request.headers.get("Authorization") - if not authorization: - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return authorization - - -class OAuth2PasswordBearer(OAuth2): - def __init__( - self, - tokenUrl: str, - scheme_name: Optional[str] = None, - scopes: Optional[dict] = None, - auto_error: bool = True, - ): - if not scopes: - scopes = {} - flows = OAuthFlowsModel(password={"tokenUrl": tokenUrl, "scopes": scopes}) - super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error) - - async def __call__(self, request: Request) -> Optional[str]: - authorization: str = request.headers.get("Authorization") - scheme, param = get_authorization_scheme_param(authorization) - if not authorization or scheme.lower() != "bearer": - if self.auto_error: - raise HTTPException( - status_code=HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - headers={"WWW-Authenticate": "Bearer"}, - ) - else: - return None - return param - - -class OAuth2AuthorizationCodeBearer(OAuth2): - def __init__( - self, - authorizationUrl: str, - tokenUrl: str, - refreshUrl: Optional[str] = None, - scheme_name: Optional[str] = None, - scopes: Optional[dict] = None, - auto_error: bool = True, - ): - if not scopes: - scopes = {} - flows = OAuthFlowsModel( - authorizationCode={ - "authorizationUrl": authorizationUrl, - "tokenUrl": tokenUrl, - "refreshUrl": refreshUrl, - "scopes": scopes, - } - ) - super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error) - - async def __call__(self, request: Request) -> Optional[str]: - authorization: str = request.headers.get("Authorization") - scheme, param = get_authorization_scheme_param(authorization) - if not authorization or scheme.lower() != "bearer": - if self.auto_error: - raise HTTPException( - status_code=HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - headers={"WWW-Authenticate": "Bearer"}, - ) - else: - return None # pragma: nocover - return param - - -class SecurityScopes: - def __init__(self, scopes: Optional[List[str]] = None): - self.scopes = scopes or [] - self.scope_str = " ".join(self.scopes) diff --git a/env/lib/python3.8/site-packages/fastapi/security/open_id_connect_url.py b/env/lib/python3.8/site-packages/fastapi/security/open_id_connect_url.py deleted file mode 100644 index a98c13f8..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/open_id_connect_url.py +++ /dev/null @@ -1,31 +0,0 @@ -from typing import Optional - -from fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel -from fastapi.security.base import SecurityBase -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.status import HTTP_403_FORBIDDEN - - -class OpenIdConnect(SecurityBase): - def __init__( - self, - *, - openIdConnectUrl: str, - scheme_name: Optional[str] = None, - auto_error: bool = True - ): - self.model = OpenIdConnectModel(openIdConnectUrl=openIdConnectUrl) - self.scheme_name = scheme_name or self.__class__.__name__ - self.auto_error = auto_error - - async def __call__(self, request: Request) -> Optional[str]: - authorization: str = request.headers.get("Authorization") - if not authorization: - if self.auto_error: - raise HTTPException( - status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - else: - return None - return authorization diff --git a/env/lib/python3.8/site-packages/fastapi/security/utils.py b/env/lib/python3.8/site-packages/fastapi/security/utils.py deleted file mode 100644 index 2da0dd20..00000000 --- a/env/lib/python3.8/site-packages/fastapi/security/utils.py +++ /dev/null @@ -1,8 +0,0 @@ -from typing import Tuple - - -def get_authorization_scheme_param(authorization_header_value: str) -> Tuple[str, str]: - if not authorization_header_value: - return "", "" - scheme, _, param = authorization_header_value.partition(" ") - return scheme, param diff --git a/env/lib/python3.8/site-packages/fastapi/staticfiles.py b/env/lib/python3.8/site-packages/fastapi/staticfiles.py deleted file mode 100644 index 78359dd1..00000000 --- a/env/lib/python3.8/site-packages/fastapi/staticfiles.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.staticfiles import StaticFiles # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/templating.py b/env/lib/python3.8/site-packages/fastapi/templating.py deleted file mode 100644 index d4c035cf..00000000 --- a/env/lib/python3.8/site-packages/fastapi/templating.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.templating import Jinja2Templates # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/testclient.py b/env/lib/python3.8/site-packages/fastapi/testclient.py deleted file mode 100644 index 0288f694..00000000 --- a/env/lib/python3.8/site-packages/fastapi/testclient.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.testclient import TestClient # noqa diff --git a/env/lib/python3.8/site-packages/fastapi/utils.py b/env/lib/python3.8/site-packages/fastapi/utils.py deleted file mode 100644 index d5ace924..00000000 --- a/env/lib/python3.8/site-packages/fastapi/utils.py +++ /dev/null @@ -1,138 +0,0 @@ -import functools -import re -from dataclasses import is_dataclass -from enum import Enum -from typing import Any, Dict, Optional, Set, Type, Union, cast - -import fastapi -from fastapi.openapi.constants import REF_PREFIX -from pydantic import BaseConfig, BaseModel, create_model -from pydantic.class_validators import Validator -from pydantic.fields import FieldInfo, ModelField, UndefinedType -from pydantic.schema import model_process_schema -from pydantic.utils import lenient_issubclass - - -def get_model_definitions( - *, - flat_models: Set[Union[Type[BaseModel], Type[Enum]]], - model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str], -) -> Dict[str, Any]: - definitions: Dict[str, Dict] = {} - for model in flat_models: - # ignore mypy error until enum schemas are released - m_schema, m_definitions, m_nested_models = model_process_schema( - model, model_name_map=model_name_map, ref_prefix=REF_PREFIX # type: ignore - ) - definitions.update(m_definitions) - model_name = model_name_map[model] - definitions[model_name] = m_schema - return definitions - - -def get_path_param_names(path: str) -> Set[str]: - return set(re.findall("{(.*?)}", path)) - - -def create_response_field( - name: str, - type_: Type[Any], - class_validators: Optional[Dict[str, Validator]] = None, - default: Optional[Any] = None, - required: Union[bool, UndefinedType] = False, - model_config: Type[BaseConfig] = BaseConfig, - field_info: Optional[FieldInfo] = None, - alias: Optional[str] = None, -) -> ModelField: - """ - Create a new response field. Raises if type_ is invalid. - """ - class_validators = class_validators or {} - field_info = field_info or FieldInfo(None) - - response_field = functools.partial( - ModelField, - name=name, - type_=type_, - class_validators=class_validators, - default=default, - required=required, - model_config=model_config, - alias=alias, - ) - - try: - return response_field(field_info=field_info) - except RuntimeError: - raise fastapi.exceptions.FastAPIError( - f"Invalid args for response field! Hint: check that {type_} is a valid pydantic field type" - ) - - -def create_cloned_field( - field: ModelField, - *, - cloned_types: Optional[Dict[Type[BaseModel], Type[BaseModel]]] = None, -) -> ModelField: - # _cloned_types has already cloned types, to support recursive models - if cloned_types is None: - cloned_types = dict() - original_type = field.type_ - if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"): - original_type = original_type.__pydantic_model__ # type: ignore - use_type = original_type - if lenient_issubclass(original_type, BaseModel): - original_type = cast(Type[BaseModel], original_type) - use_type = cloned_types.get(original_type) - if use_type is None: - use_type = create_model(original_type.__name__, __base__=original_type) - cloned_types[original_type] = use_type - for f in original_type.__fields__.values(): - use_type.__fields__[f.name] = create_cloned_field( - f, cloned_types=cloned_types - ) - new_field = create_response_field(name=field.name, type_=use_type) - new_field.has_alias = field.has_alias - new_field.alias = field.alias - new_field.class_validators = field.class_validators - new_field.default = field.default - new_field.required = field.required - new_field.model_config = field.model_config - new_field.field_info = field.field_info - new_field.allow_none = field.allow_none - new_field.validate_always = field.validate_always - if field.sub_fields: - new_field.sub_fields = [ - create_cloned_field(sub_field, cloned_types=cloned_types) - for sub_field in field.sub_fields - ] - if field.key_field: - new_field.key_field = create_cloned_field( - field.key_field, cloned_types=cloned_types - ) - new_field.validators = field.validators - new_field.pre_validators = field.pre_validators - new_field.post_validators = field.post_validators - new_field.parse_json = field.parse_json - new_field.shape = field.shape - new_field.populate_validators() - return new_field - - -def generate_operation_id_for_path(*, name: str, path: str, method: str) -> str: - operation_id = name + path - operation_id = re.sub("[^0-9a-zA-Z_]", "_", operation_id) - operation_id = operation_id + "_" + method.lower() - return operation_id - - -def deep_dict_update(main_dict: dict, update_dict: dict) -> None: - for key in update_dict: - if ( - key in main_dict - and isinstance(main_dict[key], dict) - and isinstance(update_dict[key], dict) - ): - deep_dict_update(main_dict[key], update_dict[key]) - else: - main_dict[key] = update_dict[key] diff --git a/env/lib/python3.8/site-packages/fastapi/websockets.py b/env/lib/python3.8/site-packages/fastapi/websockets.py deleted file mode 100644 index 2edf9732..00000000 --- a/env/lib/python3.8/site-packages/fastapi/websockets.py +++ /dev/null @@ -1,2 +0,0 @@ -from starlette.websockets import WebSocket # noqa -from starlette.websockets import WebSocketDisconnect # noqa diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/INSTALLER b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/LICENSE.txt b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/LICENSE.txt deleted file mode 100644 index 8f080eae..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Nathaniel J. Smith and other contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/METADATA b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/METADATA deleted file mode 100644 index 75775895..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/METADATA +++ /dev/null @@ -1,193 +0,0 @@ -Metadata-Version: 2.1 -Name: h11 -Version: 0.11.0 -Summary: A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 -Home-page: https://github.com/python-hyper/h11 -Author: Nathaniel J. Smith -Author-email: njs@pobox.com -License: MIT -Platform: UNKNOWN -Classifier: Development Status :: 3 - Alpha -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Topic :: System :: Networking - -h11 -=== - -.. image:: https://travis-ci.org/python-hyper/h11.svg?branch=master - :target: https://travis-ci.org/python-hyper/h11 - :alt: Automated test status - -.. image:: https://codecov.io/gh/python-hyper/h11/branch/master/graph/badge.svg - :target: https://codecov.io/gh/python-hyper/h11 - :alt: Test coverage - -.. image:: https://readthedocs.org/projects/h11/badge/?version=latest - :target: http://h11.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - -This is a little HTTP/1.1 library written from scratch in Python, -heavily inspired by `hyper-h2 `_. - -It's a "bring-your-own-I/O" library; h11 contains no IO code -whatsoever. This means you can hook h11 up to your favorite network -API, and that could be anything you want: synchronous, threaded, -asynchronous, or your own implementation of `RFC 6214 -`_ -- h11 won't judge you. -(Compare this to the current state of the art, where every time a `new -network API `_ comes along then someone -gets to start over reimplementing the entire HTTP protocol from -scratch.) Cory Benfield made an `excellent blog post describing the -benefits of this approach -`_, or if you like video -then here's his `PyCon 2016 talk on the same theme -`_. - -This also means that h11 is not immediately useful out of the box: -it's a toolkit for building programs that speak HTTP, not something -that could directly replace ``requests`` or ``twisted.web`` or -whatever. But h11 makes it much easier to implement something like -``requests`` or ``twisted.web``. - -At a high level, working with h11 goes like this: - -1) First, create an ``h11.Connection`` object to track the state of a - single HTTP/1.1 connection. - -2) When you read data off the network, pass it to - ``conn.receive_data(...)``; you'll get back a list of objects - representing high-level HTTP "events". - -3) When you want to send a high-level HTTP event, create the - corresponding "event" object and pass it to ``conn.send(...)``; - this will give you back some bytes that you can then push out - through the network. - -For example, a client might instantiate and then send a -``h11.Request`` object, then zero or more ``h11.Data`` objects for the -request body (e.g., if this is a POST), and then a -``h11.EndOfMessage`` to indicate the end of the message. Then the -server would then send back a ``h11.Response``, some ``h11.Data``, and -its own ``h11.EndOfMessage``. If either side violates the protocol, -you'll get a ``h11.ProtocolError`` exception. - -h11 is suitable for implementing both servers and clients, and has a -pleasantly symmetric API: the events you send as a client are exactly -the ones that you receive as a server and vice-versa. - -`Here's an example of a tiny HTTP client -`_ - -It also has `a fine manual `_. - -FAQ ---- - -*Whyyyyy?* - -I wanted to play with HTTP in `Curio -`__ and `Trio -`__, which at the time didn't have any -HTTP libraries. So I thought, no big deal, Python has, like, a dozen -different implementations of HTTP, surely I can find one that's -reusable. I didn't find one, but I did find Cory's call-to-arms -blog-post. So I figured, well, fine, if I have to implement HTTP from -scratch, at least I can make sure no-one *else* has to ever again. - -*Should I use it?* - -Maybe. You should be aware that it's a very young project. But, it's -feature complete and has an exhaustive test-suite and complete docs, -so the next step is for people to try using it and see how it goes -:-). If you do then please let us know -- if nothing else we'll want -to talk to you before making any incompatible changes! - -*What are the features/limitations?* - -Roughly speaking, it's trying to be a robust, complete, and non-hacky -implementation of the first "chapter" of the HTTP/1.1 spec: `RFC 7230: -HTTP/1.1 Message Syntax and Routing -`_. That is, it mostly focuses on -implementing HTTP at the level of taking bytes on and off the wire, -and the headers related to that, and tries to be anal about spec -conformance. It doesn't know about higher-level concerns like URL -routing, conditional GETs, cross-origin cookie policies, or content -negotiation. But it does know how to take care of framing, -cross-version differences in keep-alive handling, and the "obsolete -line folding" rule, so you can focus your energies on the hard / -interesting parts for your application, and it tries to support the -full specification in the sense that any useful HTTP/1.1 conformant -application should be able to use h11. - -It's pure Python, and has no dependencies outside of the standard -library. - -It has a test suite with 100.0% coverage for both statements and -branches. - -Currently it supports Python 3 (testing on 3.5-3.8), Python 2.7, and PyPy. -(Originally it had a Cython wrapper for `http-parser -`_ and a beautiful nested state -machine implemented with ``yield from`` to postprocess the output. But -I had to take these out -- the new *parser* needs fewer lines-of-code -than the old *parser wrapper*, is written in pure Python, uses no -exotic language syntax, and has more features. It's sad, really; that -old state machine was really slick. I just need a few sentences here -to mourn that.) - -I don't know how fast it is. I haven't benchmarked or profiled it yet, -so it's probably got a few pointless hot spots, and I've been trying -to err on the side of simplicity and robustness instead of -micro-optimization. But at the architectural level I tried hard to -avoid fundamentally bad decisions, e.g., I believe that all the -parsing algorithms remain linear-time even in the face of pathological -input like slowloris, and there are no byte-by-byte loops. (I also -believe that it maintains bounded memory usage in the face of -arbitrary/pathological input.) - -The whole library is ~800 lines-of-code. You can read and understand -the whole thing in less than an hour. Most of the energy invested in -this so far has been spent on trying to keep things simple by -minimizing special-cases and ad hoc state manipulation; even though it -is now quite small and simple, I'm still annoyed that I haven't -figured out how to make it even smaller and simpler. (Unfortunately, -HTTP does not lend itself to simplicity.) - -The API is ~feature complete and I don't expect the general outlines -to change much, but you can't judge an API's ergonomics until you -actually document and use it, so I'd expect some changes in the -details. - -*How do I try it?* - -.. code-block:: sh - - $ pip install h11 - $ git clone git@github.com:python-hyper/h11 - $ cd h11/examples - $ python basic-client.py - -and go from there. - -*License?* - -MIT - -*Code of conduct?* - -Contributors are requested to follow our `code of conduct -`_ in -all project spaces. - - diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/RECORD b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/RECORD deleted file mode 100644 index 4acbd0bf..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/RECORD +++ /dev/null @@ -1,51 +0,0 @@ -h11-0.11.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -h11-0.11.0.dist-info/LICENSE.txt,sha256=N9tbuFkm2yikJ6JYZ_ELEjIAOuob5pzLhRE4rbjm82E,1124 -h11-0.11.0.dist-info/METADATA,sha256=fOWAxk0N88NrEg1YGCUuLAPLl3OpH_gg_GiesT6pq8U,8086 -h11-0.11.0.dist-info/RECORD,, -h11-0.11.0.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 -h11-0.11.0.dist-info/top_level.txt,sha256=F7dC4jl3zeh8TGHEPaWJrMbeuoWbS379Gwdi-Yvdcis,4 -h11/__init__.py,sha256=3gYpvQiX8_6-dyXaAxQt_sIYREVTz1T-zB5Lf4hjKt0,909 -h11/__pycache__/__init__.cpython-38.pyc,, -h11/__pycache__/_abnf.cpython-38.pyc,, -h11/__pycache__/_connection.cpython-38.pyc,, -h11/__pycache__/_events.cpython-38.pyc,, -h11/__pycache__/_headers.cpython-38.pyc,, -h11/__pycache__/_readers.cpython-38.pyc,, -h11/__pycache__/_receivebuffer.cpython-38.pyc,, -h11/__pycache__/_state.cpython-38.pyc,, -h11/__pycache__/_util.cpython-38.pyc,, -h11/__pycache__/_version.cpython-38.pyc,, -h11/__pycache__/_writers.cpython-38.pyc,, -h11/_abnf.py,sha256=tMKqgOEkTHHp8sPd_gmU9Qowe_yXXrihct63RX2zJsg,4637 -h11/_connection.py,sha256=CJHlP3NRtpZJSqwexlhveNfDieR2DtZH9ZkLZUOrl18,25020 -h11/_events.py,sha256=BjWc_btWJW_N-CRUPRo68fKF8vv6hlcMs19b9oNBymc,9910 -h11/_headers.py,sha256=GCaJwi-RBZqct-lmT8ULx91_xCKYDaqtYzRqmK2CC7E,9133 -h11/_readers.py,sha256=Bcdg1Z7PtFbTAHXAU-KmVVnXwyYPeQIzmUn5jdbxh3c,7494 -h11/_receivebuffer.py,sha256=hxloIiW5b5g_cdbFAzPw-tv6YpKnDIsN4z1FUWlopcg,3911 -h11/_state.py,sha256=7YG1pJzTbwx46U_HIqKViJvf62nqGJd0g9KZ3TRR5i4,12175 -h11/_util.py,sha256=D6Pfn5Jc1TIdMjrUEpg1J_KcMvBIbCXHA9Aac5GTedM,4994 -h11/_version.py,sha256=2nBsQ_4103uOTOc7wOZBznNjYof4SLOD9lMdcXOKGB0,686 -h11/_writers.py,sha256=TWY1hK4YfKLg39gsrzaLc8u_zN_7LQJ2aMoLMrSKElU,4751 -h11/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -h11/tests/__pycache__/__init__.cpython-38.pyc,, -h11/tests/__pycache__/helpers.cpython-38.pyc,, -h11/tests/__pycache__/test_against_stdlib_http.cpython-38.pyc,, -h11/tests/__pycache__/test_connection.cpython-38.pyc,, -h11/tests/__pycache__/test_events.cpython-38.pyc,, -h11/tests/__pycache__/test_headers.cpython-38.pyc,, -h11/tests/__pycache__/test_helpers.cpython-38.pyc,, -h11/tests/__pycache__/test_io.cpython-38.pyc,, -h11/tests/__pycache__/test_receivebuffer.cpython-38.pyc,, -h11/tests/__pycache__/test_state.cpython-38.pyc,, -h11/tests/__pycache__/test_util.cpython-38.pyc,, -h11/tests/data/test-file,sha256=ZJ03Rqs98oJw29OHzJg7LlMzyGQaRAY0r3AqBeM2wVU,65 -h11/tests/helpers.py,sha256=nKheRzldPf278C81d_9_Mb9yWsYJ5udwKg_oq-fAz-U,2528 -h11/tests/test_against_stdlib_http.py,sha256=es30cmRVSTcrkNqoH5AGe_uT3ljR0OaLf2tID_17Owo,4010 -h11/tests/test_connection.py,sha256=3bWZasNIZI3CDQHp66r19IeJSCvkt4QFRa21fz16DeM,35578 -h11/tests/test_events.py,sha256=XU9YPCikxR1V5IG4yGdtsKSvwwAFNzH34Pt40TtP7vQ,5267 -h11/tests/test_headers.py,sha256=pa-WMjCk8ZXJFABkojr2db7ZKrgNKiwl-D-hjjt6-Eg,5390 -h11/tests/test_helpers.py,sha256=mPOAiv4HtyG0_T23K_ihh1JUs0y71ykD47c9r3iVtz0,573 -h11/tests/test_io.py,sha256=GFPYyMEgIQt-UnxOU--t_X_fVvHflxld2GuWWYNGBqw,14450 -h11/tests/test_receivebuffer.py,sha256=FId-lVBL3gBKmKD8gmmuZW_vdPYDtywxC3HozHI4Im0,2099 -h11/tests/test_state.py,sha256=JMKqA2d2wtskf7FbsAr1s9qsIul4WtwdXVAOCUJgalk,8551 -h11/tests/test_util.py,sha256=nlyS9b0KaP4rpsyRae0KmJ0ANNnrUjDmYaKFzz-l2RM,2711 diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/WHEEL b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/WHEEL deleted file mode 100644 index 6d38aa06..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/top_level.txt b/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/top_level.txt deleted file mode 100644 index 0d24def7..00000000 --- a/env/lib/python3.8/site-packages/h11-0.11.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -h11 diff --git a/env/lib/python3.8/site-packages/h11/__init__.py b/env/lib/python3.8/site-packages/h11/__init__.py deleted file mode 100644 index ae39e012..00000000 --- a/env/lib/python3.8/site-packages/h11/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), -# containing no networking code at all, loosely modelled on hyper-h2's generic -# implementation of HTTP/2 (and in particular the h2.connection.H2Connection -# class). There's still a bunch of subtle details you need to get right if you -# want to make this actually useful, because it doesn't implement all the -# semantics to check that what you're asking to write to the wire is sensible, -# but at least it gets you out of dealing with the wire itself. - -from ._connection import * -from ._events import * -from ._state import * -from ._util import LocalProtocolError, ProtocolError, RemoteProtocolError -from ._version import __version__ - -PRODUCT_ID = "python-h11/" + __version__ - - -__all__ = ["ProtocolError", "LocalProtocolError", "RemoteProtocolError"] -__all__ += _events.__all__ -__all__ += _connection.__all__ -__all__ += _state.__all__ diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 2a2473ff0a49414f57da34caab8d711de0456bf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmY*UOHRWu5Ve~oO%u8SB+d||)*3Z2Yh`gQ>EtQE0=21>1b9woPj;$gf4aBFbldgU z{y-f%xXexighmg2DMw9p3#X&;7eFI@agctw- diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_abnf.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_abnf.cpython-38.pyc deleted file mode 100644 index a4bd29e42efffedd8e11de1e5a08e46e7f4b94e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1196 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 S4zemHQn#!5$?{nFmH!3rW>?z) diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_events.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_events.cpython-38.pyc deleted file mode 100644 index c2194fbc178281829de75e82e95a602f2185584d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9124 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 S^3CNd%jM-4@bAL%`M&}x|EhKX diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_headers.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_headers.cpython-38.pyc deleted file mode 100644 index 3a5538ff599a9942b4902249e0b308d7cef06cd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4657 zcmb7I&2JmW72nw}Qj|n}xsKxo#fD7)u@yzBL0u=13@hOxY2T# znps-5y1Y~d3Ir&So_dvzKJ-86spq1%0>xf?Y0zWQOAl>-ZJ3BLP=6%06 zZ}^k>`HF$(?r(nY|MuI4@fR9QKMn@>@v1M;aD%hRXc^q(R>XQ{%j{V#i_zGQ?4Hwd zdTz_@m0Bfc2;;QOoio;&p`I{LE8IO}7|-glbv~Z^)Zisver53TiP@Ux%e=y8U$It| z&+++JMr(mr`2xO+e338VyTsXJqrUPr_%U|AW@zhXUg?A);(i?TL_S;ep9j%E)UCX{ z_c9eK?7YmEA0_P|`dlVy(oUjJq)cR9#7K()iLO%$dd6NCGB z)e|(rXfbZIOwL*sH(NHhxDD2f_>ERLD-y7GBy7QZI<2P#_+#aX{ zxCUu32VuQ5@ibQXT#SGPyO5>GcB{ zDsZVr!bxx2`>{A22$imC0;JxaNV^H&u6_E+lUl((&8C6e7wLAbIW;%Z>-N*t+QUSp zwKcCMUIabJy`ISZT7Au1t$mclv1pTO2z($!zXAVxE^77N3G!~5_I=1kylvMu*EdH* z>YAxQDIrr&u8-}wz3n|cXLoh4)-8zdU7|j{q&>~X-UUANvfXPbt;^uZhcormYTdg` zbtLltqIyC2|4KEV^*e(oDhRbHrp6ET>HP?=qO_E;%acyoe5wJz;1;`oJ6$XSq!|uWl9!aF9iWyiDHpeR1gf9bg%o zqB=1Jf&O2Ktw_XLV0jZrFVideKHyOH6v2fFK@Gb?k<4)}EQg>eT>1pU-h`>^=Fai_ z)(FMwyQ+SV)J_>z-XaFB;{w*E1>j|hjVTu_fEU7wj_`A(6Jm0~jJ;{V1>t~0JF_yo zGgf}#dQPEvE95Wa67jN3%?dRXX+@*mZ`SvbDJg6Cege?M16L->IbU%_LFZ0L-oP0* zUyUM!T(NHLT-ZR`BxxQKo!e;kv3Pg+Jd_xP(yz@!8;*3&X5G%s^^Lqt$&JFOkmov4 zDqG}rba32Di2{*xjk0n4?pTuZ1i8KyQ7xhFp)=m2HFvGiX3qC1!aE9;r7Ku>>hl!N z#HH`&72oeAd=OE8&i4;-6ptWqMV_=VJ>&Z-N>T-QruT; z_x3Y$=nUPAsUIT5of9^6@OANZQU!||Tj3{jCuvShi;Iz1LP?o>T zTuQm8vl%F4ZpS)f%!n5e0WL87VT|E$5p-t{%&(YyE3@TaF^^)DSAS&!yQ?{KfqCJ; z!U`AA#W9pGLHbMhf$hpnI+vN+#g}&;9N+pZio`xDqpm(mbXnv5{B1cre)AGUp8y)9 z$dEYaQ`BM&B%l4Xdm&cFsaAU&WfDY6b;vSyYMdGRxPi4M3D;4n4ExBqZ)0ih76_-D zMaTNg*1m|vi@v<~ORUoIVI!v>*W*O?Q0E*AA4Qr!E~%%2WW4Y1bnvW6V(z#G?mJP4 zY6+DhY6mUJBQ43ehCN>13-~3NqI{IfAXXiehazq#RB9gAdV?qpQH*&{#;{LDurapq zAD~`m`4SG3MEVLf>_GWl6xFH(obB!)J`ntP?ME@n-z!)?@J0)~P`q16Nq}(RR%=ywQ+CWrX(8iy! zUgtTZQfPxTa)ZhHn7=mJX%8V!CM|Gwfa8wCzEpI5f&VN{%pv3CCoXL6>?l$uu3r!I z-5+@kH#bF<_vXe%gW@NQ^*;!6(-$^v1}!;?wUR8ZlP$N{eOaP6x`FZwkPoCfC<*D` zKtz%G47&p3&M`@x*V%*ma&A(Z@Poa$BZ)srRR|^qX&4omhH^!bZc0?Egs{i=X^pF+ z8rK?vZ%{*Lw6;~j^nDr4?oo;^Dgkqm-MCwUA1+$eJC*O1o8^`N E00=)`fxT#%>cAPqND#8j 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 diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_receivebuffer.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_receivebuffer.cpython-38.pyc deleted file mode 100644 index 6707aa55dd516251bbd6c4823a364805646d43f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2489 zcmai0%WfMt6eZ`Su`Jn+9lz2xKvE!u+QvfAR~BiTCTO!L;6;K0g*L=kr0kJKGcHM| zu^|^l)qF#@$uhsu&zNmjUU%0;+jBXVW7$G7!rUQ;mz;CYJ-pNp&1Rk9y8FkU;?W{w ze^KZB6`*q;x48);ndBMkFzM~`4u8a?FTLNw6THY`bheR$Y}oRSyn& zJ*B(!^8DqYb04?q!zk9_l65@EX*n$9%K*=S??9o^H}2_+1@LLs%=zPD_i8My_;I0)qY{x2YK4wPr7zb4U_z~QTnOU zZIwT5XX#FR|IqFg`6pX<+a|T@Hv9(3t}^YtJ9pZc@95ug^l$ASma!0Nj)ldC_@;>o zJ&(PJNBn4QDpy+*$4e~vnB!P#pkbK>Gh;qR)?e}MmRANlMUj<$rgA+82Nzsr$e#d^ zgAjMnGsHNX@#)It(x*v=?$cM%ut-lIAMbmTJ@+;N;tA6W7-;!rNa-*-L{CR#WdGq_B!tY4(z)W@a!go3{W>r6LG7_DH99k2~3pv9|!K2?5%KxOWcD>P0xt z;}V3kqbp6i*zxP66pG!ND*zz6jGVB%yxh?(Tz+MEtI!q3Clu*yC#=b}C5W~XQ z?=ji9Le1BBfZsAddVg9UGv`eOM%#h*#Y0-`7Z?{9A9(r}ZRI{nT;I3B2wQpsg?^ol zy<;zrXawQ1e)u99A-I>`u|GmV#JnHjjrSyZD2c4o&**fOb$0B=X@yZhJM}mm;f?S{ zp(~^(R7g+$!_}&35>4q3lV_FaoYc;gR|dT_m#wJEdz33BGu3GrRNn61X}yh#Ue74o znakDB)hm4sYhGk{W11->BF#h&!XLxgY``$T&fi68T;MTppg;z&OH?Rty@~SI3r+3O zDLMU$#lgmzoQP%O#j*KuB_(+(qg^Mi7oPNA@?!{3vO%mLILYxB;2&=xIvH#-*l-h? z^%-)qC!>L9^4#Oh2EQR+633R?`H-dC-L-AK1{|*JHS2D3H0#a!$-l^heh(v>Ft@^U z;=O?vWoY)Z)Rqh17#u`4E%I-*F7!mxfjj%cEX`4V>0GOfEB!0elsg{<7em#Y@oQi@ z@akYY;B|fz_tA|vG41AWx0dKg$&;ZH0%tAui9E=t-4NoZgCwg)bd#W5A+rKg`sUD- z4IHBe0pLXJ6(x$Vv08}EJeDi+Bc%%=^eRnRCqt6Z?~oxH^ao^K2k2T9rTb^mLc?h& z=5Z|!Vjqzqw%Ctj^lI@6YU)Sup^qjR4#P4kcKWJo-RxP*mhrtRvae{fxNPCrzV$!U CLKq_e diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_state.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_state.cpython-38.pyc deleted file mode 100644 index 546b369c44b2ccb13b16a493ef7f0bdecdb3feee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3837 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 diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_version.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_version.cpython-38.pyc deleted file mode 100644 index 669a52a2ab01bcd3143c9a4074972571c80fda35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmWIL<>g`k0*mQ~;@2@TFgylvkO3o*;{e3P96%z4A&Mb|F_=MWHa^HWN5QtbqQR(=Lz1^{LUILZJ3 diff --git a/env/lib/python3.8/site-packages/h11/__pycache__/_writers.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/__pycache__/_writers.cpython-38.pyc deleted file mode 100644 index 77b0366b9c2fc2ac7ab0bb76578007083d932581..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4016 zcma)8&u<&Y72erjTvDV={k9#aWeY1Q8(5T(6jjqSa4a#6QI$3%wLw|8i#2B?QCjZG zGb<%hX%vWZ@3EI2?4$pU{26oY$>#t)1TE0-&61R8Nokju$9Xfev-7_9z4zvKl}gFN zv-`ZYl~0wnXfHABc{)s_6+n{J_mhH%s`)oKF=4RFBp9e`b~Zd z`Yof+3s3kvwy27t`Jcjn0DVdn#GIHF^ZfQdoUYqm;B3pPzx5inTdmg&vTkd4J<1|o zZYKQE&ToZM(XOa_+F#pv*lcZU_u=|RQx~_It@ZH1qxC=Nis^1Pw;n%gZ8f#O)!h7j zbMqC`(;I0giXY1~OFL=YlrojN@cHJ$?dIlI-G1%hYcl_&tf2qegXq{0!^cI(M_WTv z8xXtJbGy&htv~(rxszFaCu3)}{7K(_VfURE4red%W7e}E9~tzmd?s`I_8FVEUU;+) zR@*J@MXJ;7)_q;-s&1mPDCr38Jw3^U(tdP!C=#xHE;=d4aCUSU3+;=9)VizPrz(@$ zKaS!fq1u!AG9Ko-_RRk)OWwk{zx#7zFYSqj5*;bBG!c#6ZWc;$n5xE6(rp|@oor9^ zqU4?u@>s}*NRAtE_i5wsB-=}q_m@^1s+);>Sa$$#sK(yPN+bM2Voa)~!xJ5tGxt(H zM^Kd^EatL+mDsdhX7VlQW5^Q9)C{r#I(@4TY__adtYuDIx8*#B0A5cG#gI4`^0(fJa?aaeV4NXTbBAPV;rvQdpq_SoCDXDu2|{F z53X2=G49Yi9LKJ^Ek$hEOI4=Go<;RxZBbQ9-_jW?C9rxT+&PNl5RmnhF#&Eb?1_j2 zLhTtWbx}rN?UIx?vCkVo=!$tO9Bi_P6{-qhxjvf&__G5k?_z8WB{~$b z-N3(!4xt20963#hoUyMMEJhN-I5l^OPv$}M`=I^E?r$lMR+d)2n|)YIllY{jz}nhp z+uM&D7&Ql4RKQ|11T+e|yq9H%A*iOhX(A~J8cej`6JQ)zpG9(4WajAdhnNO}1u33^ z>Y1$3@^MlOu^23QA1jO>EKo3D^Gv>nkuePD*dq)+g>o5#%qIKK*bA3CFBye?=5d5E zVK73Z04=zHh}V+j3Hc6*8xRJ9Asz$-@uFUo@6rOYTssuV6A1t8NQD&LlEP>Jh!l|m zMC8L92nXB{>M%_Zt2Ka-Id8cn7 zV=_?7ehDHacL#GW=2kK1Va^}S1)Qn-S>Y>u+vLno>w$K&lS3it3%W>b3po`Gm!za` z>cEVOv}X|0lb*krX8O#FsEMyLl&lHNfZdqy51 zI$ZV$ci|bAd)&vr#|uC#&@*dklEKamk?dxB16R>T!-x9RjH`$jeb%=^lh@=OsCA|b zVQk(;TK+jkw4bXN3?Ul`fNp}y5*+2Ki;$1kvf+S6MkC=Or^oc>fqXUCumxCVzlTjNCIIzB@4N zJu)orW?3x$r)j5)(+Z;<&gm&7xSHE{vUW>3R}T1~frSS0$XqoQZNNZkodaZMPIH zTSm!Yc@d#E-aHDq;TTO(`n2c}^H&@K3AOdgd()ZU??+1g@o;DOu_$SzgEsb1Jlsc9 z|A!aLpW*JXvV4sbX(s~;-9m?sB1f8BmK%PZH~Mq}+Q0$;7r*j7P8fZ!O5bC$OmrE= zt=&3(rxQ`6ksHsWFH48_q2*d9?ot_|%qy>R&R;P(a1P>a?(*5lH?m1voU`man&^J> zm*Ex^O_D}X2n(G&B2Fhed6l@AXZF*8E@-&HE!S`2esZEv0!+13rtaot)(`3CAtc3( zq&SrY5_JESMF{PMM_D({FFA!UGzC?c2e&>{0OVy8B2>-H4b9v`w4XlR7oE(MKoj(a zGv>&Wyn2<1I`}BBxE~Xain4cLSJ@p_wteTeT`C7|Fc}0v70*=lMz!o)HXAmZncsih GfBzQ_gi4tJ diff --git a/env/lib/python3.8/site-packages/h11/_abnf.py b/env/lib/python3.8/site-packages/h11/_abnf.py deleted file mode 100644 index e6d49e1e..00000000 --- a/env/lib/python3.8/site-packages/h11/_abnf.py +++ /dev/null @@ -1,129 +0,0 @@ -# We use native strings for all the re patterns, to take advantage of string -# formatting, and then convert to bytestrings when compiling the final re -# objects. - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace -# OWS = *( SP / HTAB ) -# ; optional whitespace -OWS = r"[ \t]*" - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators -# token = 1*tchar -# -# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" -# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" -# / DIGIT / ALPHA -# ; any VCHAR, except delimiters -token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields -# field-name = token -field_name = token - -# The standard says: -# -# field-value = *( field-content / obs-fold ) -# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] -# field-vchar = VCHAR / obs-text -# obs-fold = CRLF 1*( SP / HTAB ) -# ; obsolete line folding -# ; see Section 3.2.4 -# -# https://tools.ietf.org/html/rfc5234#appendix-B.1 -# -# VCHAR = %x21-7E -# ; visible (printing) characters -# -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string -# obs-text = %x80-FF -# -# However, the standard definition of field-content is WRONG! It disallows -# fields containing a single visible character surrounded by whitespace, -# e.g. "foo a bar". -# -# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 -# -# So our definition of field_content attempts to fix it up... -# -# Also, we allow lots of control characters, because apparently people assume -# that they're legal in practice (e.g., google analytics makes cookies with -# \x01 in them!): -# https://github.com/python-hyper/h11/issues/57 -# We still don't allow NUL or whitespace, because those are often treated as -# meta-characters and letting them through can lead to nasty issues like SSRF. -vchar = r"[\x21-\x7e]" -vchar_or_obs_text = r"[^\x00\s]" -field_vchar = vchar_or_obs_text -field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) - -# We handle obs-fold at a different level, and our fixed-up field_content -# already grows to swallow the whole value, so ? instead of * -field_value = r"({field_content})?".format(**globals()) - -# header-field = field-name ":" OWS field-value OWS -header_field = ( - r"(?P{field_name})" - r":" - r"{OWS}" - r"(?P{field_value})" - r"{OWS}".format(**globals()) -) - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line -# -# request-line = method SP request-target SP HTTP-version CRLF -# method = token -# HTTP-version = HTTP-name "/" DIGIT "." DIGIT -# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive -# -# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full -# URL, host+port (for connect), or even "*", but in any case we are guaranteed -# that it contists of the visible printing characters. -method = token -request_target = r"{vchar}+".format(**globals()) -http_version = r"HTTP/(?P[0-9]\.[0-9])" -request_line = ( - r"(?P{method})" - r" " - r"(?P{request_target})" - r" " - r"{http_version}".format(**globals()) -) - -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line -# -# status-line = HTTP-version SP status-code SP reason-phrase CRLF -# status-code = 3DIGIT -# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) -status_code = r"[0-9]{3}" -reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) -status_line = ( - r"{http_version}" - r" " - r"(?P{status_code})" - # However, there are apparently a few too many servers out there that just - # leave out the reason phrase: - # https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 - # https://github.com/seanmonstar/httparse/issues/29 - # so make it optional. ?: is a non-capturing group. - r"(?: (?P{reason_phrase}))?".format(**globals()) -) - -HEXDIG = r"[0-9A-Fa-f]" -# Actually -# -# chunk-size = 1*HEXDIG -# -# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 -chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) -# Actually -# -# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) -# -# but we aren't parsing the things so we don't really care. -chunk_ext = r";.*" -chunk_header = ( - r"(?P{chunk_size})" - r"(?P{chunk_ext})?" - r"\r\n".format(**globals()) -) diff --git a/env/lib/python3.8/site-packages/h11/_connection.py b/env/lib/python3.8/site-packages/h11/_connection.py deleted file mode 100644 index 410c4e91..00000000 --- a/env/lib/python3.8/site-packages/h11/_connection.py +++ /dev/null @@ -1,586 +0,0 @@ -# This contains the main Connection class. Everything in h11 revolves around -# this. - -from ._events import * # Import all event types -from ._headers import get_comma_header, has_expect_100_continue, set_comma_header -from ._readers import READERS -from ._receivebuffer import ReceiveBuffer -from ._state import * # Import all state sentinels -from ._state import _SWITCH_CONNECT, _SWITCH_UPGRADE, ConnectionState -from ._util import ( # Import the internal things we need - LocalProtocolError, - make_sentinel, - RemoteProtocolError, -) -from ._writers import WRITERS - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = ["Connection", "NEED_DATA", "PAUSED"] - -NEED_DATA = make_sentinel("NEED_DATA") -PAUSED = make_sentinel("PAUSED") - -# If we ever have this much buffered without it making a complete parseable -# event, we error out. The only time we really buffer is when reading the -# request/reponse line + headers together, so this is effectively the limit on -# the size of that. -# -# Some precedents for defaults: -# - node.js: 80 * 1024 -# - tomcat: 8 * 1024 -# - IIS: 16 * 1024 -# - Apache: <8 KiB per line> -DEFAULT_MAX_INCOMPLETE_EVENT_SIZE = 16 * 1024 - -# RFC 7230's rules for connection lifecycles: -# - If either side says they want to close the connection, then the connection -# must close. -# - HTTP/1.1 defaults to keep-alive unless someone says Connection: close -# - HTTP/1.0 defaults to close unless both sides say Connection: keep-alive -# (and even this is a mess -- e.g. if you're implementing a proxy then -# sending Connection: keep-alive is forbidden). -# -# We simplify life by simply not supporting keep-alive with HTTP/1.0 peers. So -# our rule is: -# - If someone says Connection: close, we will close -# - If someone uses HTTP/1.0, we will close. -def _keep_alive(event): - connection = get_comma_header(event.headers, b"connection") - if b"close" in connection: - return False - if getattr(event, "http_version", b"1.1") < b"1.1": - return False - return True - - -def _body_framing(request_method, event): - # Called when we enter SEND_BODY to figure out framing information for - # this body. - # - # These are the only two events that can trigger a SEND_BODY state: - assert type(event) in (Request, Response) - # Returns one of: - # - # ("content-length", count) - # ("chunked", ()) - # ("http/1.0", ()) - # - # which are (lookup key, *args) for constructing body reader/writer - # objects. - # - # Reference: https://tools.ietf.org/html/rfc7230#section-3.3.3 - # - # Step 1: some responses always have an empty body, regardless of what the - # headers say. - if type(event) is Response: - if ( - event.status_code in (204, 304) - or request_method == b"HEAD" - or (request_method == b"CONNECT" and 200 <= event.status_code < 300) - ): - return ("content-length", (0,)) - # Section 3.3.3 also lists another case -- responses with status_code - # < 200. For us these are InformationalResponses, not Responses, so - # they can't get into this function in the first place. - assert event.status_code >= 200 - - # Step 2: check for Transfer-Encoding (T-E beats C-L): - transfer_encodings = get_comma_header(event.headers, b"transfer-encoding") - if transfer_encodings: - assert transfer_encodings == [b"chunked"] - return ("chunked", ()) - - # Step 3: check for Content-Length - content_lengths = get_comma_header(event.headers, b"content-length") - if content_lengths: - return ("content-length", (int(content_lengths[0]),)) - - # Step 4: no applicable headers; fallback/default depends on type - if type(event) is Request: - return ("content-length", (0,)) - else: - return ("http/1.0", ()) - - -################################################################ -# -# The main Connection class -# -################################################################ - - -class Connection(object): - """An object encapsulating the state of an HTTP connection. - - Args: - our_role: If you're implementing a client, pass :data:`h11.CLIENT`. If - you're implementing a server, pass :data:`h11.SERVER`. - - max_incomplete_event_size (int): - The maximum number of bytes we're willing to buffer of an - incomplete event. In practice this mostly sets a limit on the - maximum size of the request/response line + headers. If this is - exceeded, then :meth:`next_event` will raise - :exc:`RemoteProtocolError`. - - """ - - def __init__( - self, our_role, max_incomplete_event_size=DEFAULT_MAX_INCOMPLETE_EVENT_SIZE - ): - self._max_incomplete_event_size = max_incomplete_event_size - # State and role tracking - if our_role not in (CLIENT, SERVER): - raise ValueError("expected CLIENT or SERVER, not {!r}".format(our_role)) - self.our_role = our_role - if our_role is CLIENT: - self.their_role = SERVER - else: - self.their_role = CLIENT - self._cstate = ConnectionState() - - # Callables for converting data->events or vice-versa given the - # current state - self._writer = self._get_io_object(self.our_role, None, WRITERS) - self._reader = self._get_io_object(self.their_role, None, READERS) - - # Holds any unprocessed received data - self._receive_buffer = ReceiveBuffer() - # If this is true, then it indicates that the incoming connection was - # closed *after* the end of whatever's in self._receive_buffer: - self._receive_buffer_closed = False - - # Extra bits of state that don't fit into the state machine. - # - # These two are only used to interpret framing headers for figuring - # out how to read/write response bodies. their_http_version is also - # made available as a convenient public API. - self.their_http_version = None - self._request_method = None - # This is pure flow-control and doesn't at all affect the set of legal - # transitions, so no need to bother ConnectionState with it: - self.client_is_waiting_for_100_continue = False - - @property - def states(self): - """A dictionary like:: - - {CLIENT: , SERVER: } - - See :ref:`state-machine` for details. - - """ - return dict(self._cstate.states) - - @property - def our_state(self): - """The current state of whichever role we are playing. See - :ref:`state-machine` for details. - """ - return self._cstate.states[self.our_role] - - @property - def their_state(self): - """The current state of whichever role we are NOT playing. See - :ref:`state-machine` for details. - """ - return self._cstate.states[self.their_role] - - @property - def they_are_waiting_for_100_continue(self): - return self.their_role is CLIENT and self.client_is_waiting_for_100_continue - - def start_next_cycle(self): - """Attempt to reset our connection state for a new request/response - cycle. - - If both client and server are in :data:`DONE` state, then resets them - both to :data:`IDLE` state in preparation for a new request/response - cycle on this same connection. Otherwise, raises a - :exc:`LocalProtocolError`. - - See :ref:`keepalive-and-pipelining`. - - """ - old_states = dict(self._cstate.states) - self._cstate.start_next_cycle() - self._request_method = None - # self.their_http_version gets left alone, since it presumably lasts - # beyond a single request/response cycle - assert not self.client_is_waiting_for_100_continue - self._respond_to_state_changes(old_states) - - def _process_error(self, role): - old_states = dict(self._cstate.states) - self._cstate.process_error(role) - self._respond_to_state_changes(old_states) - - def _server_switch_event(self, event): - if type(event) is InformationalResponse and event.status_code == 101: - return _SWITCH_UPGRADE - if type(event) is Response: - if ( - _SWITCH_CONNECT in self._cstate.pending_switch_proposals - and 200 <= event.status_code < 300 - ): - return _SWITCH_CONNECT - return None - - # All events go through here - def _process_event(self, role, event): - # First, pass the event through the state machine to make sure it - # succeeds. - old_states = dict(self._cstate.states) - if role is CLIENT and type(event) is Request: - if event.method == b"CONNECT": - self._cstate.process_client_switch_proposal(_SWITCH_CONNECT) - if get_comma_header(event.headers, b"upgrade"): - self._cstate.process_client_switch_proposal(_SWITCH_UPGRADE) - server_switch_event = None - if role is SERVER: - server_switch_event = self._server_switch_event(event) - self._cstate.process_event(role, type(event), server_switch_event) - - # Then perform the updates triggered by it. - - # self._request_method - if type(event) is Request: - self._request_method = event.method - - # self.their_http_version - if role is self.their_role and type(event) in ( - Request, - Response, - InformationalResponse, - ): - self.their_http_version = event.http_version - - # Keep alive handling - # - # RFC 7230 doesn't really say what one should do if Connection: close - # shows up on a 1xx InformationalResponse. I think the idea is that - # this is not supposed to happen. In any case, if it does happen, we - # ignore it. - if type(event) in (Request, Response) and not _keep_alive(event): - self._cstate.process_keep_alive_disabled() - - # 100-continue - if type(event) is Request and has_expect_100_continue(event): - self.client_is_waiting_for_100_continue = True - if type(event) in (InformationalResponse, Response): - self.client_is_waiting_for_100_continue = False - if role is CLIENT and type(event) in (Data, EndOfMessage): - self.client_is_waiting_for_100_continue = False - - self._respond_to_state_changes(old_states, event) - - def _get_io_object(self, role, event, io_dict): - # event may be None; it's only used when entering SEND_BODY - state = self._cstate.states[role] - if state is SEND_BODY: - # Special case: the io_dict has a dict of reader/writer factories - # that depend on the request/response framing. - framing_type, args = _body_framing(self._request_method, event) - return io_dict[SEND_BODY][framing_type](*args) - else: - # General case: the io_dict just has the appropriate reader/writer - # for this state - return io_dict.get((role, state)) - - # This must be called after any action that might have caused - # self._cstate.states to change. - def _respond_to_state_changes(self, old_states, event=None): - # Update reader/writer - if self.our_state != old_states[self.our_role]: - self._writer = self._get_io_object(self.our_role, event, WRITERS) - if self.their_state != old_states[self.their_role]: - self._reader = self._get_io_object(self.their_role, event, READERS) - - @property - def trailing_data(self): - """Data that has been received, but not yet processed, represented as - a tuple with two elements, where the first is a byte-string containing - the unprocessed data itself, and the second is a bool that is True if - the receive connection was closed. - - See :ref:`switching-protocols` for discussion of why you'd want this. - """ - return (bytes(self._receive_buffer), self._receive_buffer_closed) - - def receive_data(self, data): - """Add data to our internal receive buffer. - - This does not actually do any processing on the data, just stores - it. To trigger processing, you have to call :meth:`next_event`. - - Args: - data (:term:`bytes-like object`): - The new data that was just received. - - Special case: If *data* is an empty byte-string like ``b""``, - then this indicates that the remote side has closed the - connection (end of file). Normally this is convenient, because - standard Python APIs like :meth:`file.read` or - :meth:`socket.recv` use ``b""`` to indicate end-of-file, while - other failures to read are indicated using other mechanisms - like raising :exc:`TimeoutError`. When using such an API you - can just blindly pass through whatever you get from ``read`` - to :meth:`receive_data`, and everything will work. - - But, if you have an API where reading an empty string is a - valid non-EOF condition, then you need to be aware of this and - make sure to check for such strings and avoid passing them to - :meth:`receive_data`. - - Returns: - Nothing, but after calling this you should call :meth:`next_event` - to parse the newly received data. - - Raises: - RuntimeError: - Raised if you pass an empty *data*, indicating EOF, and then - pass a non-empty *data*, indicating more data that somehow - arrived after the EOF. - - (Calling ``receive_data(b"")`` multiple times is fine, - and equivalent to calling it once.) - - """ - if data: - if self._receive_buffer_closed: - raise RuntimeError("received close, then received more data?") - self._receive_buffer += data - else: - self._receive_buffer_closed = True - - def _extract_next_receive_event(self): - state = self.their_state - # We don't pause immediately when they enter DONE, because even in - # DONE state we can still process a ConnectionClosed() event. But - # if we have data in our buffer, then we definitely aren't getting - # a ConnectionClosed() immediately and we need to pause. - if state is DONE and self._receive_buffer: - return PAUSED - if state is MIGHT_SWITCH_PROTOCOL or state is SWITCHED_PROTOCOL: - return PAUSED - assert self._reader is not None - event = self._reader(self._receive_buffer) - if event is None: - if not self._receive_buffer and self._receive_buffer_closed: - # In some unusual cases (basically just HTTP/1.0 bodies), EOF - # triggers an actual protocol event; in that case, we want to - # return that event, and then the state will change and we'll - # get called again to generate the actual ConnectionClosed(). - if hasattr(self._reader, "read_eof"): - event = self._reader.read_eof() - else: - event = ConnectionClosed() - if event is None: - event = NEED_DATA - return event - - def next_event(self): - """Parse the next event out of our receive buffer, update our internal - state, and return it. - - This is a mutating operation -- think of it like calling :func:`next` - on an iterator. - - Returns: - : One of three things: - - 1) An event object -- see :ref:`events`. - - 2) The special constant :data:`NEED_DATA`, which indicates that - you need to read more data from your socket and pass it to - :meth:`receive_data` before this method will be able to return - any more events. - - 3) The special constant :data:`PAUSED`, which indicates that we - are not in a state where we can process incoming data (usually - because the peer has finished their part of the current - request/response cycle, and you have not yet called - :meth:`start_next_cycle`). See :ref:`flow-control` for details. - - Raises: - RemoteProtocolError: - The peer has misbehaved. You should close the connection - (possibly after sending some kind of 4xx response). - - Once this method returns :class:`ConnectionClosed` once, then all - subsequent calls will also return :class:`ConnectionClosed`. - - If this method raises any exception besides :exc:`RemoteProtocolError` - then that's a bug -- if it happens please file a bug report! - - If this method raises any exception then it also sets - :attr:`Connection.their_state` to :data:`ERROR` -- see - :ref:`error-handling` for discussion. - - """ - - if self.their_state is ERROR: - raise RemoteProtocolError("Can't receive data when peer state is ERROR") - try: - event = self._extract_next_receive_event() - if event not in [NEED_DATA, PAUSED]: - self._process_event(self.their_role, event) - self._receive_buffer.compress() - if event is NEED_DATA: - if len(self._receive_buffer) > self._max_incomplete_event_size: - # 431 is "Request header fields too large" which is pretty - # much the only situation where we can get here - raise RemoteProtocolError( - "Receive buffer too long", error_status_hint=431 - ) - if self._receive_buffer_closed: - # We're still trying to complete some event, but that's - # never going to happen because no more data is coming - raise RemoteProtocolError("peer unexpectedly closed connection") - return event - except BaseException as exc: - self._process_error(self.their_role) - if isinstance(exc, LocalProtocolError): - exc._reraise_as_remote_protocol_error() - else: - raise - - def send(self, event): - """Convert a high-level event into bytes that can be sent to the peer, - while updating our internal state machine. - - Args: - event: The :ref:`event ` to send. - - Returns: - If ``type(event) is ConnectionClosed``, then returns - ``None``. Otherwise, returns a :term:`bytes-like object`. - - Raises: - LocalProtocolError: - Sending this event at this time would violate our - understanding of the HTTP/1.1 protocol. - - If this method raises any exception then it also sets - :attr:`Connection.our_state` to :data:`ERROR` -- see - :ref:`error-handling` for discussion. - - """ - data_list = self.send_with_data_passthrough(event) - if data_list is None: - return None - else: - return b"".join(data_list) - - def send_with_data_passthrough(self, event): - """Identical to :meth:`send`, except that in situations where - :meth:`send` returns a single :term:`bytes-like object`, this instead - returns a list of them -- and when sending a :class:`Data` event, this - list is guaranteed to contain the exact object you passed in as - :attr:`Data.data`. See :ref:`sendfile` for discussion. - - """ - if self.our_state is ERROR: - raise LocalProtocolError("Can't send data when our state is ERROR") - try: - if type(event) is Response: - self._clean_up_response_headers_for_sending(event) - # We want to call _process_event before calling the writer, - # because if someone tries to do something invalid then this will - # give a sensible error message, while our writers all just assume - # they will only receive valid events. But, _process_event might - # change self._writer. So we have to do a little dance: - writer = self._writer - self._process_event(self.our_role, event) - if type(event) is ConnectionClosed: - return None - else: - # In any situation where writer is None, process_event should - # have raised ProtocolError - assert writer is not None - data_list = [] - writer(event, data_list.append) - return data_list - except: - self._process_error(self.our_role) - raise - - def send_failed(self): - """Notify the state machine that we failed to send the data it gave - us. - - This causes :attr:`Connection.our_state` to immediately become - :data:`ERROR` -- see :ref:`error-handling` for discussion. - - """ - self._process_error(self.our_role) - - # When sending a Response, we take responsibility for a few things: - # - # - Sometimes you MUST set Connection: close. We take care of those - # times. (You can also set it yourself if you want, and if you do then - # we'll respect that and close the connection at the right time. But you - # don't have to worry about that unless you want to.) - # - # - The user has to set Content-Length if they want it. Otherwise, for - # responses that have bodies (e.g. not HEAD), then we will automatically - # select the right mechanism for streaming a body of unknown length, - # which depends on depending on the peer's HTTP version. - # - # This function's *only* responsibility is making sure headers are set up - # right -- everything downstream just looks at the headers. There are no - # side channels. It mutates the response event in-place (but not the - # response.headers list object). - def _clean_up_response_headers_for_sending(self, response): - assert type(response) is Response - - headers = response.headers - need_close = False - - # HEAD requests need some special handling: they always act like they - # have Content-Length: 0, and that's how _body_framing treats - # them. But their headers are supposed to match what we would send if - # the request was a GET. (Technically there is one deviation allowed: - # we're allowed to leave out the framing headers -- see - # https://tools.ietf.org/html/rfc7231#section-4.3.2 . But it's just as - # easy to get them right.) - method_for_choosing_headers = self._request_method - if method_for_choosing_headers == b"HEAD": - method_for_choosing_headers = b"GET" - framing_type, _ = _body_framing(method_for_choosing_headers, response) - if framing_type in ("chunked", "http/1.0"): - # This response has a body of unknown length. - # If our peer is HTTP/1.1, we use Transfer-Encoding: chunked - # If our peer is HTTP/1.0, we use no framing headers, and close the - # connection afterwards. - # - # Make sure to clear Content-Length (in principle user could have - # set both and then we ignored Content-Length b/c - # Transfer-Encoding overwrote it -- this would be naughty of them, - # but the HTTP spec says that if our peer does this then we have - # to fix it instead of erroring out, so we'll accord the user the - # same respect). - headers = set_comma_header(headers, b"content-length", []) - if self.their_http_version is None or self.their_http_version < b"1.1": - # Either we never got a valid request and are sending back an - # error (their_http_version is None), so we assume the worst; - # or else we did get a valid HTTP/1.0 request, so we know that - # they don't understand chunked encoding. - headers = set_comma_header(headers, b"transfer-encoding", []) - # This is actually redundant ATM, since currently we - # unconditionally disable keep-alive when talking to HTTP/1.0 - # peers. But let's be defensive just in case we add - # Connection: keep-alive support later: - if self._request_method != b"HEAD": - need_close = True - else: - headers = set_comma_header(headers, b"transfer-encoding", ["chunked"]) - - if not self._cstate.keep_alive or need_close: - # Make sure Connection: close is set - connection = set(get_comma_header(headers, b"connection")) - connection.discard(b"keep-alive") - connection.add(b"close") - headers = set_comma_header(headers, b"connection", sorted(connection)) - - response.headers = headers diff --git a/env/lib/python3.8/site-packages/h11/_events.py b/env/lib/python3.8/site-packages/h11/_events.py deleted file mode 100644 index c11d838a..00000000 --- a/env/lib/python3.8/site-packages/h11/_events.py +++ /dev/null @@ -1,305 +0,0 @@ -# High level events that make up HTTP/1.1 conversations. Loosely inspired by -# the corresponding events in hyper-h2: -# -# http://python-hyper.org/h2/en/stable/api.html#events -# -# Don't subclass these. Stuff will break. - -import re - -from . import _headers -from ._abnf import request_target -from ._util import bytesify, LocalProtocolError, validate - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = [ - "Request", - "InformationalResponse", - "Response", - "Data", - "EndOfMessage", - "ConnectionClosed", -] - -request_target_re = re.compile(request_target.encode("ascii")) - - -class _EventBundle(object): - _fields = [] - _defaults = {} - - def __init__(self, **kwargs): - _parsed = kwargs.pop("_parsed", False) - allowed = set(self._fields) - for kwarg in kwargs: - if kwarg not in allowed: - raise TypeError( - "unrecognized kwarg {} for {}".format( - kwarg, self.__class__.__name__ - ) - ) - required = allowed.difference(self._defaults) - for field in required: - if field not in kwargs: - raise TypeError( - "missing required kwarg {} for {}".format( - field, self.__class__.__name__ - ) - ) - self.__dict__.update(self._defaults) - self.__dict__.update(kwargs) - - # Special handling for some fields - - if "headers" in self.__dict__: - self.headers = _headers.normalize_and_validate( - self.headers, _parsed=_parsed - ) - - if not _parsed: - for field in ["method", "target", "http_version", "reason"]: - if field in self.__dict__: - self.__dict__[field] = bytesify(self.__dict__[field]) - - if "status_code" in self.__dict__: - if not isinstance(self.status_code, int): - raise LocalProtocolError("status code must be integer") - # Because IntEnum objects are instances of int, but aren't - # duck-compatible (sigh), see gh-72. - self.status_code = int(self.status_code) - - self._validate() - - def _validate(self): - pass - - def __repr__(self): - name = self.__class__.__name__ - kwarg_strs = [ - "{}={}".format(field, self.__dict__[field]) for field in self._fields - ] - kwarg_str = ", ".join(kwarg_strs) - return "{}({})".format(name, kwarg_str) - - # Useful for tests - def __eq__(self, other): - return self.__class__ == other.__class__ and self.__dict__ == other.__dict__ - - def __ne__(self, other): - return not self.__eq__(other) - - # This is an unhashable type. - __hash__ = None - - -class Request(_EventBundle): - """The beginning of an HTTP request. - - Fields: - - .. attribute:: method - - An HTTP method, e.g. ``b"GET"`` or ``b"POST"``. Always a byte - string. :term:`Bytes-like objects ` and native - strings containing only ascii characters will be automatically - converted to byte strings. - - .. attribute:: target - - The target of an HTTP request, e.g. ``b"/index.html"``, or one of the - more exotic formats described in `RFC 7320, section 5.3 - `_. Always a byte - string. :term:`Bytes-like objects ` and native - strings containing only ascii characters will be automatically - converted to byte strings. - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - """ - - _fields = ["method", "target", "headers", "http_version"] - _defaults = {"http_version": b"1.1"} - - def _validate(self): - # "A server MUST respond with a 400 (Bad Request) status code to any - # HTTP/1.1 request message that lacks a Host header field and to any - # request message that contains more than one Host header field or a - # Host header field with an invalid field-value." - # -- https://tools.ietf.org/html/rfc7230#section-5.4 - host_count = 0 - for name, value in self.headers: - if name == b"host": - host_count += 1 - if self.http_version == b"1.1" and host_count == 0: - raise LocalProtocolError("Missing mandatory Host: header") - if host_count > 1: - raise LocalProtocolError("Found multiple Host: headers") - - validate(request_target_re, self.target, "Illegal target characters") - - -class _ResponseBase(_EventBundle): - _fields = ["status_code", "headers", "http_version", "reason"] - _defaults = {"http_version": b"1.1", "reason": b""} - - -class InformationalResponse(_ResponseBase): - """An HTTP informational response. - - Fields: - - .. attribute:: status_code - - The status code of this response, as an integer. For an - :class:`InformationalResponse`, this is always in the range [100, - 200). - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for - details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - .. attribute:: reason - - The reason phrase of this response, as a byte string. For example: - ``b"OK"``, or ``b"Not Found"``. - - """ - - def _validate(self): - if not (100 <= self.status_code < 200): - raise LocalProtocolError( - "InformationalResponse status_code should be in range " - "[100, 200), not {}".format(self.status_code) - ) - - -class Response(_ResponseBase): - """The beginning of an HTTP response. - - Fields: - - .. attribute:: status_code - - The status code of this response, as an integer. For an - :class:`Response`, this is always in the range [200, - 600). - - .. attribute:: headers - - Request headers, represented as a list of (name, value) pairs. See - :ref:`the header normalization rules ` for details. - - .. attribute:: http_version - - The HTTP protocol version, represented as a byte string like - ``b"1.1"``. See :ref:`the HTTP version normalization rules - ` for details. - - .. attribute:: reason - - The reason phrase of this response, as a byte string. For example: - ``b"OK"``, or ``b"Not Found"``. - - """ - - def _validate(self): - if not (200 <= self.status_code < 600): - raise LocalProtocolError( - "Response status_code should be in range [200, 600), not {}".format( - self.status_code - ) - ) - - -class Data(_EventBundle): - """Part of an HTTP message body. - - Fields: - - .. attribute:: data - - A :term:`bytes-like object` containing part of a message body. Or, if - using the ``combine=False`` argument to :meth:`Connection.send`, then - any object that your socket writing code knows what to do with, and for - which calling :func:`len` returns the number of bytes that will be - written -- see :ref:`sendfile` for details. - - .. attribute:: chunk_start - - A marker that indicates whether this data object is from the start of a - chunked transfer encoding chunk. This field is ignored when when a Data - event is provided to :meth:`Connection.send`: it is only valid on - events emitted from :meth:`Connection.next_event`. You probably - shouldn't use this attribute at all; see - :ref:`chunk-delimiters-are-bad` for details. - - .. attribute:: chunk_end - - A marker that indicates whether this data object is the last for a - given chunked transfer encoding chunk. This field is ignored when when - a Data event is provided to :meth:`Connection.send`: it is only valid - on events emitted from :meth:`Connection.next_event`. You probably - shouldn't use this attribute at all; see - :ref:`chunk-delimiters-are-bad` for details. - - """ - - _fields = ["data", "chunk_start", "chunk_end"] - _defaults = {"chunk_start": False, "chunk_end": False} - - -# XX FIXME: "A recipient MUST ignore (or consider as an error) any fields that -# are forbidden to be sent in a trailer, since processing them as if they were -# present in the header section might bypass external security filters." -# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#chunked.trailer.part -# Unfortunately, the list of forbidden fields is long and vague :-/ -class EndOfMessage(_EventBundle): - """The end of an HTTP message. - - Fields: - - .. attribute:: headers - - Default value: ``[]`` - - Any trailing headers attached to this message, represented as a list of - (name, value) pairs. See :ref:`the header normalization rules - ` for details. - - Must be empty unless ``Transfer-Encoding: chunked`` is in use. - - """ - - _fields = ["headers"] - _defaults = {"headers": []} - - -class ConnectionClosed(_EventBundle): - """This event indicates that the sender has closed their outgoing - connection. - - Note that this does not necessarily mean that they can't *receive* further - data, because TCP connections are composed to two one-way channels which - can be closed independently. See :ref:`closing` for details. - - No fields. - """ - - pass diff --git a/env/lib/python3.8/site-packages/h11/_headers.py b/env/lib/python3.8/site-packages/h11/_headers.py deleted file mode 100644 index 5229ac40..00000000 --- a/env/lib/python3.8/site-packages/h11/_headers.py +++ /dev/null @@ -1,242 +0,0 @@ -import re - -from ._abnf import field_name, field_value -from ._util import bytesify, LocalProtocolError, validate - -# Facts -# ----- -# -# Headers are: -# keys: case-insensitive ascii -# values: mixture of ascii and raw bytes -# -# "Historically, HTTP has allowed field content with text in the ISO-8859-1 -# charset [ISO-8859-1], supporting other charsets only through use of -# [RFC2047] encoding. In practice, most HTTP header field values use only a -# subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD -# limit their field values to US-ASCII octets. A recipient SHOULD treat other -# octets in field content (obs-text) as opaque data." -# And it deprecates all non-ascii values -# -# Leading/trailing whitespace in header names is forbidden -# -# Values get leading/trailing whitespace stripped -# -# Content-Disposition actually needs to contain unicode semantically; to -# accomplish this it has a terrifically weird way of encoding the filename -# itself as ascii (and even this still has lots of cross-browser -# incompatibilities) -# -# Order is important: -# "a proxy MUST NOT change the order of these field values when forwarding a -# message" -# (and there are several headers where the order indicates a preference) -# -# Multiple occurences of the same header: -# "A sender MUST NOT generate multiple header fields with the same field name -# in a message unless either the entire field value for that header field is -# defined as a comma-separated list [or the header is Set-Cookie which gets a -# special exception]" - RFC 7230. (cookies are in RFC 6265) -# -# So every header aside from Set-Cookie can be merged by b", ".join if it -# occurs repeatedly. But, of course, they can't necessarily be split by -# .split(b","), because quoting. -# -# Given all this mess (case insensitive, duplicates allowed, order is -# important, ...), there doesn't appear to be any standard way to handle -# headers in Python -- they're almost like dicts, but... actually just -# aren't. For now we punt and just use a super simple representation: headers -# are a list of pairs -# -# [(name1, value1), (name2, value2), ...] -# -# where all entries are bytestrings, names are lowercase and have no -# leading/trailing whitespace, and values are bytestrings with no -# leading/trailing whitespace. Searching and updating are done via naive O(n) -# methods. -# -# Maybe a dict-of-lists would be better? - -_content_length_re = re.compile(br"[0-9]+") -_field_name_re = re.compile(field_name.encode("ascii")) -_field_value_re = re.compile(field_value.encode("ascii")) - - -class Headers: - """ - A list-like interface that allows iterating over headers as byte-pairs - of (lowercased-name, value). - - Internally we actually store the representation as three-tuples, - including both the raw original casing, in order to preserve casing - over-the-wire, and the lowercased name, for case-insensitive comparisions. - - r = Request( - method="GET", - target="/", - headers=[("Host", "example.org"), ("Connection", "keep-alive")], - http_version="1.1", - ) - assert r.headers == [ - (b"host", b"example.org"), - (b"connection", b"keep-alive") - ] - assert r.headers.raw_items() == [ - (b"Host", b"example.org"), - (b"Connection", b"keep-alive") - ] - """ - - __slots__ = "_full_items" - - def __init__(self, full_items): - self._full_items = full_items - - def __iter__(self): - for _, name, value in self._full_items: - yield name, value - - def __bool__(self): - return bool(self._full_items) - - def __eq__(self, other): - return list(self) == list(other) - - def __len__(self): - return len(self._full_items) - - def __repr__(self): - return "" % repr(list(self)) - - def __getitem__(self, idx): - _, name, value = self._full_items[idx] - return (name, value) - - def raw_items(self): - return [(raw_name, value) for raw_name, _, value in self._full_items] - - -def normalize_and_validate(headers, _parsed=False): - new_headers = [] - seen_content_length = None - saw_transfer_encoding = False - for name, value in headers: - # For headers coming out of the parser, we can safely skip some steps, - # because it always returns bytes and has already run these regexes - # over the data: - if not _parsed: - name = bytesify(name) - value = bytesify(value) - validate(_field_name_re, name, "Illegal header name {!r}", name) - validate(_field_value_re, value, "Illegal header value {!r}", value) - raw_name = name - name = name.lower() - if name == b"content-length": - lengths = set(length.strip() for length in value.split(b",")) - if len(lengths) != 1: - raise LocalProtocolError("conflicting Content-Length headers") - value = lengths.pop() - validate(_content_length_re, value, "bad Content-Length") - if seen_content_length is None: - seen_content_length = value - new_headers.append((raw_name, name, value)) - elif seen_content_length != value: - raise LocalProtocolError("conflicting Content-Length headers") - elif name == b"transfer-encoding": - # "A server that receives a request message with a transfer coding - # it does not understand SHOULD respond with 501 (Not - # Implemented)." - # https://tools.ietf.org/html/rfc7230#section-3.3.1 - if saw_transfer_encoding: - raise LocalProtocolError( - "multiple Transfer-Encoding headers", error_status_hint=501 - ) - # "All transfer-coding names are case-insensitive" - # -- https://tools.ietf.org/html/rfc7230#section-4 - value = value.lower() - if value != b"chunked": - raise LocalProtocolError( - "Only Transfer-Encoding: chunked is supported", - error_status_hint=501, - ) - saw_transfer_encoding = True - new_headers.append((raw_name, name, value)) - else: - new_headers.append((raw_name, name, value)) - return Headers(new_headers) - - -def get_comma_header(headers, name): - # Should only be used for headers whose value is a list of - # comma-separated, case-insensitive values. - # - # The header name `name` is expected to be lower-case bytes. - # - # Connection: meets these criteria (including cast insensitivity). - # - # Content-Length: technically is just a single value (1*DIGIT), but the - # standard makes reference to implementations that do multiple values, and - # using this doesn't hurt. Ditto, case insensitivity doesn't things either - # way. - # - # Transfer-Encoding: is more complex (allows for quoted strings), so - # splitting on , is actually wrong. For example, this is legal: - # - # Transfer-Encoding: foo; options="1,2", chunked - # - # and should be parsed as - # - # foo; options="1,2" - # chunked - # - # but this naive function will parse it as - # - # foo; options="1 - # 2" - # chunked - # - # However, this is okay because the only thing we are going to do with - # any Transfer-Encoding is reject ones that aren't just "chunked", so - # both of these will be treated the same anyway. - # - # Expect: the only legal value is the literal string - # "100-continue". Splitting on commas is harmless. Case insensitive. - # - out = [] - for _, found_name, found_raw_value in headers._full_items: - if found_name == name: - found_raw_value = found_raw_value.lower() - for found_split_value in found_raw_value.split(b","): - found_split_value = found_split_value.strip() - if found_split_value: - out.append(found_split_value) - return out - - -def set_comma_header(headers, name, new_values): - # The header name `name` is expected to be lower-case bytes. - # - # Note that when we store the header we use title casing for the header - # names, in order to match the conventional HTTP header style. - # - # Simply calling `.title()` is a blunt approach, but it's correct - # here given the cases where we're using `set_comma_header`... - # - # Connection, Content-Length, Transfer-Encoding. - new_headers = [] - for found_raw_name, found_name, found_raw_value in headers._full_items: - if found_name != name: - new_headers.append((found_raw_name, found_raw_value)) - for new_value in new_values: - new_headers.append((name.title(), new_value)) - return normalize_and_validate(new_headers) - - -def has_expect_100_continue(request): - # https://tools.ietf.org/html/rfc7231#section-5.1.1 - # "A server that receives a 100-continue expectation in an HTTP/1.0 request - # MUST ignore that expectation." - if request.http_version < b"1.1": - return False - expect = get_comma_header(request.headers, b"expect") - return b"100-continue" in expect diff --git a/env/lib/python3.8/site-packages/h11/_readers.py b/env/lib/python3.8/site-packages/h11/_readers.py deleted file mode 100644 index cc86bffb..00000000 --- a/env/lib/python3.8/site-packages/h11/_readers.py +++ /dev/null @@ -1,226 +0,0 @@ -# Code to read HTTP data -# -# Strategy: each reader is a callable which takes a ReceiveBuffer object, and -# either: -# 1) consumes some of it and returns an Event -# 2) raises a LocalProtocolError (for consistency -- e.g. we call validate() -# and it might raise a LocalProtocolError, so simpler just to always use -# this) -# 3) returns None, meaning "I need more data" -# -# If they have a .read_eof attribute, then this will be called if an EOF is -# received -- but this is optional. Either way, the actual ConnectionClosed -# event will be generated afterwards. -# -# READERS is a dict describing how to pick a reader. It maps states to either: -# - a reader -# - or, for body readers, a dict of per-framing reader factories - -import re - -from ._abnf import chunk_header, header_field, request_line, status_line -from ._events import * -from ._state import * -from ._util import LocalProtocolError, RemoteProtocolError, validate - -__all__ = ["READERS"] - -header_field_re = re.compile(header_field.encode("ascii")) - -# Remember that this has to run in O(n) time -- so e.g. the bytearray cast is -# critical. -obs_fold_re = re.compile(br"[ \t]+") - - -def _obsolete_line_fold(lines): - it = iter(lines) - last = None - for line in it: - match = obs_fold_re.match(line) - if match: - if last is None: - raise LocalProtocolError("continuation line at start of headers") - if not isinstance(last, bytearray): - last = bytearray(last) - last += b" " - last += line[match.end() :] - else: - if last is not None: - yield last - last = line - if last is not None: - yield last - - -def _decode_header_lines(lines): - for line in _obsolete_line_fold(lines): - # _obsolete_line_fold yields either bytearray or bytes objects. On - # Python 3, validate() takes either and returns matches as bytes. But - # on Python 2, validate can return matches as bytearrays, so we have - # to explicitly cast back. - matches = validate( - header_field_re, bytes(line), "illegal header line: {!r}", bytes(line) - ) - yield (matches["field_name"], matches["field_value"]) - - -request_line_re = re.compile(request_line.encode("ascii")) - - -def maybe_read_from_IDLE_client(buf): - lines = buf.maybe_extract_lines() - if lines is None: - return None - if not lines: - raise LocalProtocolError("no request line received") - matches = validate( - request_line_re, lines[0], "illegal request line: {!r}", lines[0] - ) - return Request( - headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches - ) - - -status_line_re = re.compile(status_line.encode("ascii")) - - -def maybe_read_from_SEND_RESPONSE_server(buf): - lines = buf.maybe_extract_lines() - if lines is None: - return None - if not lines: - raise LocalProtocolError("no response line received") - matches = validate(status_line_re, lines[0], "illegal status line: {!r}", lines[0]) - # Tolerate missing reason phrases - if matches["reason"] is None: - matches["reason"] = b"" - status_code = matches["status_code"] = int(matches["status_code"]) - class_ = InformationalResponse if status_code < 200 else Response - return class_( - headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches - ) - - -class ContentLengthReader: - def __init__(self, length): - self._length = length - self._remaining = length - - def __call__(self, buf): - if self._remaining == 0: - return EndOfMessage() - data = buf.maybe_extract_at_most(self._remaining) - if data is None: - return None - self._remaining -= len(data) - return Data(data=data) - - def read_eof(self): - raise RemoteProtocolError( - "peer closed connection without sending complete message body " - "(received {} bytes, expected {})".format( - self._length - self._remaining, self._length - ) - ) - - -chunk_header_re = re.compile(chunk_header.encode("ascii")) - - -class ChunkedReader(object): - def __init__(self): - self._bytes_in_chunk = 0 - # After reading a chunk, we have to throw away the trailing \r\n; if - # this is >0 then we discard that many bytes before resuming regular - # de-chunkification. - self._bytes_to_discard = 0 - self._reading_trailer = False - - def __call__(self, buf): - if self._reading_trailer: - lines = buf.maybe_extract_lines() - if lines is None: - return None - return EndOfMessage(headers=list(_decode_header_lines(lines))) - if self._bytes_to_discard > 0: - data = buf.maybe_extract_at_most(self._bytes_to_discard) - if data is None: - return None - self._bytes_to_discard -= len(data) - if self._bytes_to_discard > 0: - return None - # else, fall through and read some more - assert self._bytes_to_discard == 0 - if self._bytes_in_chunk == 0: - # We need to refill our chunk count - chunk_header = buf.maybe_extract_until_next(b"\r\n") - if chunk_header is None: - return None - matches = validate( - chunk_header_re, - chunk_header, - "illegal chunk header: {!r}", - chunk_header, - ) - # XX FIXME: we discard chunk extensions. Does anyone care? - # We convert to bytes because Python 2's `int()` function doesn't - # work properly on bytearray objects. - self._bytes_in_chunk = int(bytes(matches["chunk_size"]), base=16) - if self._bytes_in_chunk == 0: - self._reading_trailer = True - return self(buf) - chunk_start = True - else: - chunk_start = False - assert self._bytes_in_chunk > 0 - data = buf.maybe_extract_at_most(self._bytes_in_chunk) - if data is None: - return None - self._bytes_in_chunk -= len(data) - if self._bytes_in_chunk == 0: - self._bytes_to_discard = 2 - chunk_end = True - else: - chunk_end = False - return Data(data=data, chunk_start=chunk_start, chunk_end=chunk_end) - - def read_eof(self): - raise RemoteProtocolError( - "peer closed connection without sending complete message body " - "(incomplete chunked read)" - ) - - -class Http10Reader(object): - def __call__(self, buf): - data = buf.maybe_extract_at_most(999999999) - if data is None: - return None - return Data(data=data) - - def read_eof(self): - return EndOfMessage() - - -def expect_nothing(buf): - if buf: - raise LocalProtocolError("Got data when expecting EOF") - return None - - -READERS = { - (CLIENT, IDLE): maybe_read_from_IDLE_client, - (SERVER, IDLE): maybe_read_from_SEND_RESPONSE_server, - (SERVER, SEND_RESPONSE): maybe_read_from_SEND_RESPONSE_server, - (CLIENT, DONE): expect_nothing, - (CLIENT, MUST_CLOSE): expect_nothing, - (CLIENT, CLOSED): expect_nothing, - (SERVER, DONE): expect_nothing, - (SERVER, MUST_CLOSE): expect_nothing, - (SERVER, CLOSED): expect_nothing, - SEND_BODY: { - "chunked": ChunkedReader, - "content-length": ContentLengthReader, - "http/1.0": Http10Reader, - }, -} diff --git a/env/lib/python3.8/site-packages/h11/_receivebuffer.py b/env/lib/python3.8/site-packages/h11/_receivebuffer.py deleted file mode 100644 index c56749a3..00000000 --- a/env/lib/python3.8/site-packages/h11/_receivebuffer.py +++ /dev/null @@ -1,112 +0,0 @@ -import sys - -__all__ = ["ReceiveBuffer"] - - -# Operations we want to support: -# - find next \r\n or \r\n\r\n, or wait until there is one -# - read at-most-N bytes -# Goals: -# - on average, do this fast -# - worst case, do this in O(n) where n is the number of bytes processed -# Plan: -# - store bytearray, offset, how far we've searched for a separator token -# - use the how-far-we've-searched data to avoid rescanning -# - while doing a stream of uninterrupted processing, advance offset instead -# of constantly copying -# WARNING: -# - I haven't benchmarked or profiled any of this yet. -# -# Note that starting in Python 3.4, deleting the initial n bytes from a -# bytearray is amortized O(n), thanks to some excellent work by Antoine -# Martin: -# -# https://bugs.python.org/issue19087 -# -# This means that if we only supported 3.4+, we could get rid of the code here -# involving self._start and self.compress, because it's doing exactly the same -# thing that bytearray now does internally. -# -# BUT unfortunately, we still support 2.7, and reading short segments out of a -# long buffer MUST be O(bytes read) to avoid DoS issues, so we can't actually -# delete this code. Yet: -# -# https://pythonclock.org/ -# -# (Two things to double-check first though: make sure PyPy also has the -# optimization, and benchmark to make sure it's a win, since we do have a -# slightly clever thing where we delay calling compress() until we've -# processed a whole event, which could in theory be slightly more efficient -# than the internal bytearray support.) -class ReceiveBuffer(object): - def __init__(self): - self._data = bytearray() - # These are both absolute offsets into self._data: - self._start = 0 - self._looked_at = 0 - self._looked_for = b"" - - def __bool__(self): - return bool(len(self)) - - # for @property unprocessed_data - def __bytes__(self): - return bytes(self._data[self._start :]) - - if sys.version_info[0] < 3: # version specific: Python 2 - __str__ = __bytes__ - __nonzero__ = __bool__ - - def __len__(self): - return len(self._data) - self._start - - def compress(self): - # Heuristic: only compress if it lets us reduce size by a factor - # of 2 - if self._start > len(self._data) // 2: - del self._data[: self._start] - self._looked_at -= self._start - self._start -= self._start - - def __iadd__(self, byteslike): - self._data += byteslike - return self - - def maybe_extract_at_most(self, count): - out = self._data[self._start : self._start + count] - if not out: - return None - self._start += len(out) - return out - - def maybe_extract_until_next(self, needle): - # Returns extracted bytes on success (advancing offset), or None on - # failure - if self._looked_for == needle: - search_start = max(self._start, self._looked_at - len(needle) + 1) - else: - search_start = self._start - offset = self._data.find(needle, search_start) - if offset == -1: - self._looked_at = len(self._data) - self._looked_for = needle - return None - new_start = offset + len(needle) - out = self._data[self._start : new_start] - self._start = new_start - return out - - # HTTP/1.1 has a number of constructs where you keep reading lines until - # you see a blank one. This does that, and then returns the lines. - def maybe_extract_lines(self): - if self._data[self._start : self._start + 2] == b"\r\n": - self._start += 2 - return [] - else: - data = self.maybe_extract_until_next(b"\r\n\r\n") - if data is None: - return None - lines = data.split(b"\r\n") - assert lines[-2] == lines[-1] == b"" - del lines[-2:] - return lines diff --git a/env/lib/python3.8/site-packages/h11/_state.py b/env/lib/python3.8/site-packages/h11/_state.py deleted file mode 100644 index 70a5e049..00000000 --- a/env/lib/python3.8/site-packages/h11/_state.py +++ /dev/null @@ -1,307 +0,0 @@ -################################################################ -# The core state machine -################################################################ -# -# Rule 1: everything that affects the state machine and state transitions must -# live here in this file. As much as possible goes into the table-based -# representation, but for the bits that don't quite fit, the actual code and -# state must nonetheless live here. -# -# Rule 2: this file does not know about what role we're playing; it only knows -# about HTTP request/response cycles in the abstract. This ensures that we -# don't cheat and apply different rules to local and remote parties. -# -# -# Theory of operation -# =================== -# -# Possibly the simplest way to think about this is that we actually have 5 -# different state machines here. Yes, 5. These are: -# -# 1) The client state, with its complicated automaton (see the docs) -# 2) The server state, with its complicated automaton (see the docs) -# 3) The keep-alive state, with possible states {True, False} -# 4) The SWITCH_CONNECT state, with possible states {False, True} -# 5) The SWITCH_UPGRADE state, with possible states {False, True} -# -# For (3)-(5), the first state listed is the initial state. -# -# (1)-(3) are stored explicitly in member variables. The last -# two are stored implicitly in the pending_switch_proposals set as: -# (state of 4) == (_SWITCH_CONNECT in pending_switch_proposals) -# (state of 5) == (_SWITCH_UPGRADE in pending_switch_proposals) -# -# And each of these machines has two different kinds of transitions: -# -# a) Event-triggered -# b) State-triggered -# -# Event triggered is the obvious thing that you'd think it is: some event -# happens, and if it's the right event at the right time then a transition -# happens. But there are somewhat complicated rules for which machines can -# "see" which events. (As a rule of thumb, if a machine "sees" an event, this -# means two things: the event can affect the machine, and if the machine is -# not in a state where it expects that event then it's an error.) These rules -# are: -# -# 1) The client machine sees all h11.events objects emitted by the client. -# -# 2) The server machine sees all h11.events objects emitted by the server. -# -# It also sees the client's Request event. -# -# And sometimes, server events are annotated with a _SWITCH_* event. For -# example, we can have a (Response, _SWITCH_CONNECT) event, which is -# different from a regular Response event. -# -# 3) The keep-alive machine sees the process_keep_alive_disabled() event -# (which is derived from Request/Response events), and this event -# transitions it from True -> False, or from False -> False. There's no way -# to transition back. -# -# 4&5) The _SWITCH_* machines transition from False->True when we get a -# Request that proposes the relevant type of switch (via -# process_client_switch_proposals), and they go from True->False when we -# get a Response that has no _SWITCH_* annotation. -# -# So that's event-triggered transitions. -# -# State-triggered transitions are less standard. What they do here is couple -# the machines together. The way this works is, when certain *joint* -# configurations of states are achieved, then we automatically transition to a -# new *joint* state. So, for example, if we're ever in a joint state with -# -# client: DONE -# keep-alive: False -# -# then the client state immediately transitions to: -# -# client: MUST_CLOSE -# -# This is fundamentally different from an event-based transition, because it -# doesn't matter how we arrived at the {client: DONE, keep-alive: False} state -# -- maybe the client transitioned SEND_BODY -> DONE, or keep-alive -# transitioned True -> False. Either way, once this precondition is satisfied, -# this transition is immediately triggered. -# -# What if two conflicting state-based transitions get enabled at the same -# time? In practice there's only one case where this arises (client DONE -> -# MIGHT_SWITCH_PROTOCOL versus DONE -> MUST_CLOSE), and we resolve it by -# explicitly prioritizing the DONE -> MIGHT_SWITCH_PROTOCOL transition. -# -# Implementation -# -------------- -# -# The event-triggered transitions for the server and client machines are all -# stored explicitly in a table. Ditto for the state-triggered transitions that -# involve just the server and client state. -# -# The transitions for the other machines, and the state-triggered transitions -# that involve the other machines, are written out as explicit Python code. -# -# It'd be nice if there were some cleaner way to do all this. This isn't -# *too* terrible, but I feel like it could probably be better. -# -# WARNING -# ------- -# -# The script that generates the state machine diagrams for the docs knows how -# to read out the EVENT_TRIGGERED_TRANSITIONS and STATE_TRIGGERED_TRANSITIONS -# tables. But it can't automatically read the transitions that are written -# directly in Python code. So if you touch those, you need to also update the -# script to keep it in sync! - -from ._events import * -from ._util import LocalProtocolError, make_sentinel - -# Everything in __all__ gets re-exported as part of the h11 public API. -__all__ = [ - "CLIENT", - "SERVER", - "IDLE", - "SEND_RESPONSE", - "SEND_BODY", - "DONE", - "MUST_CLOSE", - "CLOSED", - "MIGHT_SWITCH_PROTOCOL", - "SWITCHED_PROTOCOL", - "ERROR", -] - -CLIENT = make_sentinel("CLIENT") -SERVER = make_sentinel("SERVER") - -# States -IDLE = make_sentinel("IDLE") -SEND_RESPONSE = make_sentinel("SEND_RESPONSE") -SEND_BODY = make_sentinel("SEND_BODY") -DONE = make_sentinel("DONE") -MUST_CLOSE = make_sentinel("MUST_CLOSE") -CLOSED = make_sentinel("CLOSED") -ERROR = make_sentinel("ERROR") - -# Switch types -MIGHT_SWITCH_PROTOCOL = make_sentinel("MIGHT_SWITCH_PROTOCOL") -SWITCHED_PROTOCOL = make_sentinel("SWITCHED_PROTOCOL") - -_SWITCH_UPGRADE = make_sentinel("_SWITCH_UPGRADE") -_SWITCH_CONNECT = make_sentinel("_SWITCH_CONNECT") - -EVENT_TRIGGERED_TRANSITIONS = { - CLIENT: { - IDLE: {Request: SEND_BODY, ConnectionClosed: CLOSED}, - SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, - DONE: {ConnectionClosed: CLOSED}, - MUST_CLOSE: {ConnectionClosed: CLOSED}, - CLOSED: {ConnectionClosed: CLOSED}, - MIGHT_SWITCH_PROTOCOL: {}, - SWITCHED_PROTOCOL: {}, - ERROR: {}, - }, - SERVER: { - IDLE: { - ConnectionClosed: CLOSED, - Response: SEND_BODY, - # Special case: server sees client Request events, in this form - (Request, CLIENT): SEND_RESPONSE, - }, - SEND_RESPONSE: { - InformationalResponse: SEND_RESPONSE, - Response: SEND_BODY, - (InformationalResponse, _SWITCH_UPGRADE): SWITCHED_PROTOCOL, - (Response, _SWITCH_CONNECT): SWITCHED_PROTOCOL, - }, - SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, - DONE: {ConnectionClosed: CLOSED}, - MUST_CLOSE: {ConnectionClosed: CLOSED}, - CLOSED: {ConnectionClosed: CLOSED}, - SWITCHED_PROTOCOL: {}, - ERROR: {}, - }, -} - -# NB: there are also some special-case state-triggered transitions hard-coded -# into _fire_state_triggered_transitions below. -STATE_TRIGGERED_TRANSITIONS = { - # (Client state, Server state) -> new states - # Protocol negotiation - (MIGHT_SWITCH_PROTOCOL, SWITCHED_PROTOCOL): {CLIENT: SWITCHED_PROTOCOL}, - # Socket shutdown - (CLOSED, DONE): {SERVER: MUST_CLOSE}, - (CLOSED, IDLE): {SERVER: MUST_CLOSE}, - (ERROR, DONE): {SERVER: MUST_CLOSE}, - (DONE, CLOSED): {CLIENT: MUST_CLOSE}, - (IDLE, CLOSED): {CLIENT: MUST_CLOSE}, - (DONE, ERROR): {CLIENT: MUST_CLOSE}, -} - - -class ConnectionState(object): - def __init__(self): - # Extra bits of state that don't quite fit into the state model. - - # If this is False then it enables the automatic DONE -> MUST_CLOSE - # transition. Don't set this directly; call .keep_alive_disabled() - self.keep_alive = True - - # This is a subset of {UPGRADE, CONNECT}, containing the proposals - # made by the client for switching protocols. - self.pending_switch_proposals = set() - - self.states = {CLIENT: IDLE, SERVER: IDLE} - - def process_error(self, role): - self.states[role] = ERROR - self._fire_state_triggered_transitions() - - def process_keep_alive_disabled(self): - self.keep_alive = False - self._fire_state_triggered_transitions() - - def process_client_switch_proposal(self, switch_event): - self.pending_switch_proposals.add(switch_event) - self._fire_state_triggered_transitions() - - def process_event(self, role, event_type, server_switch_event=None): - if server_switch_event is not None: - assert role is SERVER - if server_switch_event not in self.pending_switch_proposals: - raise LocalProtocolError( - "Received server {} event without a pending proposal".format( - server_switch_event - ) - ) - event_type = (event_type, server_switch_event) - if server_switch_event is None and event_type is Response: - self.pending_switch_proposals = set() - self._fire_event_triggered_transitions(role, event_type) - # Special case: the server state does get to see Request - # events. - if event_type is Request: - assert role is CLIENT - self._fire_event_triggered_transitions(SERVER, (Request, CLIENT)) - self._fire_state_triggered_transitions() - - def _fire_event_triggered_transitions(self, role, event_type): - state = self.states[role] - try: - new_state = EVENT_TRIGGERED_TRANSITIONS[role][state][event_type] - except KeyError: - raise LocalProtocolError( - "can't handle event type {} when role={} and state={}".format( - event_type.__name__, role, self.states[role] - ) - ) - self.states[role] = new_state - - def _fire_state_triggered_transitions(self): - # We apply these rules repeatedly until converging on a fixed point - while True: - start_states = dict(self.states) - - # It could happen that both these special-case transitions are - # enabled at the same time: - # - # DONE -> MIGHT_SWITCH_PROTOCOL - # DONE -> MUST_CLOSE - # - # For example, this will always be true of a HTTP/1.0 client - # requesting CONNECT. If this happens, the protocol switch takes - # priority. From there the client will either go to - # SWITCHED_PROTOCOL, in which case it's none of our business when - # they close the connection, or else the server will deny the - # request, in which case the client will go back to DONE and then - # from there to MUST_CLOSE. - if self.pending_switch_proposals: - if self.states[CLIENT] is DONE: - self.states[CLIENT] = MIGHT_SWITCH_PROTOCOL - - if not self.pending_switch_proposals: - if self.states[CLIENT] is MIGHT_SWITCH_PROTOCOL: - self.states[CLIENT] = DONE - - if not self.keep_alive: - for role in (CLIENT, SERVER): - if self.states[role] is DONE: - self.states[role] = MUST_CLOSE - - # Tabular state-triggered transitions - joint_state = (self.states[CLIENT], self.states[SERVER]) - changes = STATE_TRIGGERED_TRANSITIONS.get(joint_state, {}) - self.states.update(changes) - - if self.states == start_states: - # Fixed point reached - return - - def start_next_cycle(self): - if self.states != {CLIENT: DONE, SERVER: DONE}: - raise LocalProtocolError( - "not in a reusable state. self.states={}".format(self.states) - ) - # Can't reach DONE/DONE with any of these active, but still, let's be - # sure. - assert self.keep_alive - assert not self.pending_switch_proposals - self.states = {CLIENT: IDLE, SERVER: IDLE} diff --git a/env/lib/python3.8/site-packages/h11/_util.py b/env/lib/python3.8/site-packages/h11/_util.py deleted file mode 100644 index 0a2c28e0..00000000 --- a/env/lib/python3.8/site-packages/h11/_util.py +++ /dev/null @@ -1,142 +0,0 @@ -import re -import sys - -__all__ = [ - "ProtocolError", - "LocalProtocolError", - "RemoteProtocolError", - "validate", - "make_sentinel", - "bytesify", -] - - -class ProtocolError(Exception): - """Exception indicating a violation of the HTTP/1.1 protocol. - - This as an abstract base class, with two concrete base classes: - :exc:`LocalProtocolError`, which indicates that you tried to do something - that HTTP/1.1 says is illegal, and :exc:`RemoteProtocolError`, which - indicates that the remote peer tried to do something that HTTP/1.1 says is - illegal. See :ref:`error-handling` for details. - - In addition to the normal :exc:`Exception` features, it has one attribute: - - .. attribute:: error_status_hint - - This gives a suggestion as to what status code a server might use if - this error occurred as part of a request. - - For a :exc:`RemoteProtocolError`, this is useful as a suggestion for - how you might want to respond to a misbehaving peer, if you're - implementing a server. - - For a :exc:`LocalProtocolError`, this can be taken as a suggestion for - how your peer might have responded to *you* if h11 had allowed you to - continue. - - The default is 400 Bad Request, a generic catch-all for protocol - violations. - - """ - - def __init__(self, msg, error_status_hint=400): - if type(self) is ProtocolError: - raise TypeError("tried to directly instantiate ProtocolError") - Exception.__init__(self, msg) - self.error_status_hint = error_status_hint - - -# Strategy: there are a number of public APIs where a LocalProtocolError can -# be raised (send(), all the different event constructors, ...), and only one -# public API where RemoteProtocolError can be raised -# (receive_data()). Therefore we always raise LocalProtocolError internally, -# and then receive_data will translate this into a RemoteProtocolError. -# -# Internally: -# LocalProtocolError is the generic "ProtocolError". -# Externally: -# LocalProtocolError is for local errors and RemoteProtocolError is for -# remote errors. -class LocalProtocolError(ProtocolError): - def _reraise_as_remote_protocol_error(self): - # After catching a LocalProtocolError, use this method to re-raise it - # as a RemoteProtocolError. This method must be called from inside an - # except: block. - # - # An easy way to get an equivalent RemoteProtocolError is just to - # modify 'self' in place. - self.__class__ = RemoteProtocolError - # But the re-raising is somewhat non-trivial -- you might think that - # now that we've modified the in-flight exception object, that just - # doing 'raise' to re-raise it would be enough. But it turns out that - # this doesn't work, because Python tracks the exception type - # (exc_info[0]) separately from the exception object (exc_info[1]), - # and we only modified the latter. So we really do need to re-raise - # the new type explicitly. - if sys.version_info[0] >= 3: - # On py3, the traceback is part of the exception object, so our - # in-place modification preserved it and we can just re-raise: - raise self - else: - # On py2, preserving the traceback requires 3-argument - # raise... but on py3 this is a syntax error, so we have to hide - # it inside an exec - exec("raise RemoteProtocolError, self, sys.exc_info()[2]") - - -class RemoteProtocolError(ProtocolError): - pass - - -try: - _fullmatch = type(re.compile("")).fullmatch -except AttributeError: - - def _fullmatch(regex, data): # version specific: Python < 3.4 - match = regex.match(data) - if match and match.end() != len(data): - match = None - return match - - -def validate(regex, data, msg="malformed data", *format_args): - match = _fullmatch(regex, data) - if not match: - if format_args: - msg = msg.format(*format_args) - raise LocalProtocolError(msg) - return match.groupdict() - - -# Sentinel values -# -# - Inherit identity-based comparison and hashing from object -# - Have a nice repr -# - Have a *bonus property*: type(sentinel) is sentinel -# -# The bonus property is useful if you want to take the return value from -# next_event() and do some sort of dispatch based on type(event). -class _SentinelBase(type): - def __repr__(self): - return self.__name__ - - -def make_sentinel(name): - cls = _SentinelBase(name, (_SentinelBase,), {}) - cls.__class__ = cls - return cls - - -# Used for methods, request targets, HTTP versions, header names, and header -# values. Accepts ascii-strings, or bytes/bytearray/memoryview/..., and always -# returns bytes. -def bytesify(s): - # Fast-path: - if type(s) is bytes: - return s - if isinstance(s, str): - s = s.encode("ascii") - if isinstance(s, int): - raise TypeError("expected bytes-like object, not int") - return bytes(s) diff --git a/env/lib/python3.8/site-packages/h11/_version.py b/env/lib/python3.8/site-packages/h11/_version.py deleted file mode 100644 index f050fa51..00000000 --- a/env/lib/python3.8/site-packages/h11/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# This file must be kept very simple, because it is consumed from several -# places -- it is imported by h11/__init__.py, execfile'd by setup.py, etc. - -# We use a simple scheme: -# 1.0.0 -> 1.0.0+dev -> 1.1.0 -> 1.1.0+dev -# where the +dev versions are never released into the wild, they're just what -# we stick into the VCS in between releases. -# -# This is compatible with PEP 440: -# http://legacy.python.org/dev/peps/pep-0440/ -# via the use of the "local suffix" "+dev", which is disallowed on index -# servers and causes 1.0.0+dev to sort after plain 1.0.0, which is what we -# want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* -# 1.0.0.) - -__version__ = "0.11.0" diff --git a/env/lib/python3.8/site-packages/h11/_writers.py b/env/lib/python3.8/site-packages/h11/_writers.py deleted file mode 100644 index 7531579c..00000000 --- a/env/lib/python3.8/site-packages/h11/_writers.py +++ /dev/null @@ -1,143 +0,0 @@ -# Code to read HTTP data -# -# Strategy: each writer takes an event + a write-some-bytes function, which is -# calls. -# -# WRITERS is a dict describing how to pick a reader. It maps states to either: -# - a writer -# - or, for body writers, a dict of framin-dependent writer factories - -import sys - -from ._events import Data, EndOfMessage -from ._state import CLIENT, IDLE, SEND_BODY, SEND_RESPONSE, SERVER -from ._util import LocalProtocolError - -__all__ = ["WRITERS"] - -# Equivalent of bstr % values, that works on python 3.x for x < 5 -if (3, 0) <= sys.version_info < (3, 5): - - def bytesmod(bstr, values): - decoded_values = [] - for value in values: - if isinstance(value, bytes): - decoded_values.append(value.decode("ascii")) - else: - decoded_values.append(value) - return (bstr.decode("ascii") % tuple(decoded_values)).encode("ascii") - - -else: - - def bytesmod(bstr, values): - return bstr % values - - -def write_headers(headers, write): - # "Since the Host field-value is critical information for handling a - # request, a user agent SHOULD generate Host as the first header field - # following the request-line." - RFC 7230 - raw_items = headers._full_items - for raw_name, name, value in raw_items: - if name == b"host": - write(bytesmod(b"%s: %s\r\n", (raw_name, value))) - for raw_name, name, value in raw_items: - if name != b"host": - write(bytesmod(b"%s: %s\r\n", (raw_name, value))) - write(b"\r\n") - - -def write_request(request, write): - if request.http_version != b"1.1": - raise LocalProtocolError("I only send HTTP/1.1") - write(bytesmod(b"%s %s HTTP/1.1\r\n", (request.method, request.target))) - write_headers(request.headers, write) - - -# Shared between InformationalResponse and Response -def write_any_response(response, write): - if response.http_version != b"1.1": - raise LocalProtocolError("I only send HTTP/1.1") - status_bytes = str(response.status_code).encode("ascii") - # We don't bother sending ascii status messages like "OK"; they're - # optional and ignored by the protocol. (But the space after the numeric - # status code is mandatory.) - # - # XX FIXME: could at least make an effort to pull out the status message - # from stdlib's http.HTTPStatus table. Or maybe just steal their enums - # (either by import or copy/paste). We already accept them as status codes - # since they're of type IntEnum < int. - write(bytesmod(b"HTTP/1.1 %s %s\r\n", (status_bytes, response.reason))) - write_headers(response.headers, write) - - -class BodyWriter(object): - def __call__(self, event, write): - if type(event) is Data: - self.send_data(event.data, write) - elif type(event) is EndOfMessage: - self.send_eom(event.headers, write) - else: # pragma: no cover - assert False - - -# -# These are all careful not to do anything to 'data' except call len(data) and -# write(data). This allows us to transparently pass-through funny objects, -# like placeholder objects referring to files on disk that will be sent via -# sendfile(2). -# -class ContentLengthWriter(BodyWriter): - def __init__(self, length): - self._length = length - - def send_data(self, data, write): - self._length -= len(data) - if self._length < 0: - raise LocalProtocolError("Too much data for declared Content-Length") - write(data) - - def send_eom(self, headers, write): - if self._length != 0: - raise LocalProtocolError("Too little data for declared Content-Length") - if headers: - raise LocalProtocolError("Content-Length and trailers don't mix") - - -class ChunkedWriter(BodyWriter): - def send_data(self, data, write): - # if we encoded 0-length data in the naive way, it would look like an - # end-of-message. - if not data: - return - write(bytesmod(b"%x\r\n", (len(data),))) - write(data) - write(b"\r\n") - - def send_eom(self, headers, write): - write(b"0\r\n") - write_headers(headers, write) - - -class Http10Writer(BodyWriter): - def send_data(self, data, write): - write(data) - - def send_eom(self, headers, write): - if headers: - raise LocalProtocolError("can't send trailers to HTTP/1.0 client") - # no need to close the socket ourselves, that will be taken care of by - # Connection: close machinery - - -WRITERS = { - (CLIENT, IDLE): write_request, - (SERVER, IDLE): write_any_response, - (SERVER, SEND_RESPONSE): write_any_response, - SEND_BODY: { - "chunked": ChunkedWriter, - "content-length": ContentLengthWriter, - "http/1.0": Http10Writer, - }, -} diff --git a/env/lib/python3.8/site-packages/h11/tests/__init__.py b/env/lib/python3.8/site-packages/h11/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 39ba49e6e537aef613fa06e3b0725c87ab1205bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmWIL<>g`kg6g(I@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vEza+OnzaXTZl OX-=vg$h^-$%m4s%h#@ur diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/helpers.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/helpers.cpython-38.pyc deleted file mode 100644 index b63f0e054d55cae0aa7ecdcd21160873f2017dba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1957 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 Y@Jkl0?u}i}!pa2Z#@w1;JU4dse-&han*aa+ diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_connection.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_connection.cpython-38.pyc deleted file mode 100644 index 1af2600d91332e319374abec0239eeff764dbd59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31180 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 I^47lp3%fMWyZ`_I diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_events.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_events.cpython-38.pyc deleted file mode 100644 index ca47866d67efb806d0db53ab298dc31293dde6c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3682 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 diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_helpers.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_helpers.cpython-38.pyc deleted file mode 100644 index e945b20390df15b7cf50f313b148e521e6347f6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 636 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 diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-38.pyc deleted file mode 100644 index 2ea4013c22118ef820c88b1b717c1f4c620ff24b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1437 zcmZWpzi-n(6uz?)$GCM!(-umL5Ms;FMrjI#3RMM!#MGgP#RHL(yR=c9#JY0|5h+89 z5M%y?RAOP{Pe4q}j9!_-T8RNM@a{(wTeWoW?tSn3zPo3g{mOM61kbyV-)mJHpz6tqj#UE$R z5k`^n5%{sjvm|?ti3P|fh47JdP$$R%K9;#s+K_+M%A}*fe`q{Qu7RUK;)GJ1{dbCi z+BW~EkP&8=y|}{iwCDAyr(hSPgX~|w z59l8Bx_`2eVk_^@+NqeTElS%RYB`{5(smo=YTQ&=ulO}hHNuja}o z&jCx76b3e2xM~azF!R6UtwG&&{GGdX*J<{8J9VGAj_X9sZw0OHAs3&Os7iB9;P5r0 zDMR!Gk_myC&m}4V%I#-vC7X%9V)O6 z6|VQYq2Fjzvi|0X(qMhyvqreptd)-{l`ufbC0vxl#<0pj1P!b#p%k?uy!jtiL|EGZ diff --git a/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_state.cpython-38.pyc b/env/lib/python3.8/site-packages/h11/tests/__pycache__/test_state.cpython-38.pyc deleted file mode 100644 index f2b17c0d090f221794d798c627385229f2d1dc6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4959 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 diff --git a/env/lib/python3.8/site-packages/h11/tests/data/test-file b/env/lib/python3.8/site-packages/h11/tests/data/test-file deleted file mode 100644 index d0be0a6c..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/data/test-file +++ /dev/null @@ -1 +0,0 @@ -92b12bc045050b55b848d37167a1a63947c364579889ce1d39788e45e9fac9e5 diff --git a/env/lib/python3.8/site-packages/h11/tests/helpers.py b/env/lib/python3.8/site-packages/h11/tests/helpers.py deleted file mode 100644 index 9d2cf380..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/helpers.py +++ /dev/null @@ -1,77 +0,0 @@ -from .._connection import * -from .._events import * -from .._state import * - - -def get_all_events(conn): - got_events = [] - while True: - event = conn.next_event() - if event in (NEED_DATA, PAUSED): - break - got_events.append(event) - if type(event) is ConnectionClosed: - break - return got_events - - -def receive_and_get(conn, data): - conn.receive_data(data) - return get_all_events(conn) - - -# Merges adjacent Data events, converts payloads to bytestrings, and removes -# chunk boundaries. -def normalize_data_events(in_events): - out_events = [] - for event in in_events: - if type(event) is Data: - event.data = bytes(event.data) - event.chunk_start = False - event.chunk_end = False - if out_events and type(out_events[-1]) is type(event) is Data: - out_events[-1].data += event.data - else: - out_events.append(event) - return out_events - - -# Given that we want to write tests that push some events through a Connection -# and check that its state updates appropriately... we might as make a habit -# of pushing them through two Connections with a fake network link in -# between. -class ConnectionPair: - def __init__(self): - self.conn = {CLIENT: Connection(CLIENT), SERVER: Connection(SERVER)} - self.other = {CLIENT: SERVER, SERVER: CLIENT} - - @property - def conns(self): - return self.conn.values() - - # expect="match" if expect=send_events; expect=[...] to say what expected - def send(self, role, send_events, expect="match"): - if not isinstance(send_events, list): - send_events = [send_events] - data = b"" - closed = False - for send_event in send_events: - new_data = self.conn[role].send(send_event) - if new_data is None: - closed = True - else: - data += new_data - # send uses b"" to mean b"", and None to mean closed - # receive uses b"" to mean closed, and None to mean "try again" - # so we have to translate between the two conventions - if data: - self.conn[self.other[role]].receive_data(data) - if closed: - self.conn[self.other[role]].receive_data(b"") - got_events = get_all_events(self.conn[self.other[role]]) - if expect == "match": - expect = send_events - if not isinstance(expect, list): - expect = [expect] - assert got_events == expect - return data diff --git a/env/lib/python3.8/site-packages/h11/tests/test_against_stdlib_http.py b/env/lib/python3.8/site-packages/h11/tests/test_against_stdlib_http.py deleted file mode 100644 index b4219ffe..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_against_stdlib_http.py +++ /dev/null @@ -1,123 +0,0 @@ -import json -import os.path -import socket -import threading -from contextlib import closing, contextmanager - -import h11 - -try: - from urllib.request import urlopen -except ImportError: # version specific: Python 2 - from urllib2 import urlopen - -try: - import socketserver -except ImportError: # version specific: Python 2 - import SocketServer as socketserver - -try: - from http.server import SimpleHTTPRequestHandler -except ImportError: # version specific: Python 2 - from SimpleHTTPServer import SimpleHTTPRequestHandler - - -@contextmanager -def socket_server(handler): - httpd = socketserver.TCPServer(("127.0.0.1", 0), handler) - thread = threading.Thread( - target=httpd.serve_forever, kwargs={"poll_interval": 0.01} - ) - thread.daemon = True - try: - thread.start() - yield httpd - finally: - httpd.shutdown() - - -test_file_path = os.path.join(os.path.dirname(__file__), "data/test-file") -with open(test_file_path, "rb") as f: - test_file_data = f.read() - - -class SingleMindedRequestHandler(SimpleHTTPRequestHandler): - def translate_path(self, path): - return test_file_path - - -def test_h11_as_client(): - with socket_server(SingleMindedRequestHandler) as httpd: - with closing(socket.create_connection(httpd.server_address)) as s: - c = h11.Connection(h11.CLIENT) - - s.sendall( - c.send( - h11.Request( - method="GET", target="/foo", headers=[("Host", "localhost")] - ) - ) - ) - s.sendall(c.send(h11.EndOfMessage())) - - data = bytearray() - while True: - event = c.next_event() - print(event) - if event is h11.NEED_DATA: - # Use a small read buffer to make things more challenging - # and exercise more paths :-) - c.receive_data(s.recv(10)) - continue - if type(event) is h11.Response: - assert event.status_code == 200 - if type(event) is h11.Data: - data += event.data - if type(event) is h11.EndOfMessage: - break - assert bytes(data) == test_file_data - - -class H11RequestHandler(socketserver.BaseRequestHandler): - def handle(self): - with closing(self.request) as s: - c = h11.Connection(h11.SERVER) - request = None - while True: - event = c.next_event() - if event is h11.NEED_DATA: - # Use a small read buffer to make things more challenging - # and exercise more paths :-) - c.receive_data(s.recv(10)) - continue - if type(event) is h11.Request: - request = event - if type(event) is h11.EndOfMessage: - break - info = json.dumps( - { - "method": request.method.decode("ascii"), - "target": request.target.decode("ascii"), - "headers": { - name.decode("ascii"): value.decode("ascii") - for (name, value) in request.headers - }, - } - ) - s.sendall(c.send(h11.Response(status_code=200, headers=[]))) - s.sendall(c.send(h11.Data(data=info.encode("ascii")))) - s.sendall(c.send(h11.EndOfMessage())) - - -def test_h11_as_server(): - with socket_server(H11RequestHandler) as httpd: - host, port = httpd.server_address - url = "http://{}:{}/some-path".format(host, port) - with closing(urlopen(url)) as f: - assert f.getcode() == 200 - data = f.read() - info = json.loads(data.decode("ascii")) - print(info) - assert info["method"] == "GET" - assert info["target"] == "/some-path" - assert "urllib" in info["headers"]["user-agent"] diff --git a/env/lib/python3.8/site-packages/h11/tests/test_connection.py b/env/lib/python3.8/site-packages/h11/tests/test_connection.py deleted file mode 100644 index a43113ec..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_connection.py +++ /dev/null @@ -1,1046 +0,0 @@ -import pytest - -from .._connection import _body_framing, _keep_alive, Connection, NEED_DATA, PAUSED -from .._events import * -from .._state import * -from .._util import LocalProtocolError, RemoteProtocolError -from .helpers import ConnectionPair, get_all_events, receive_and_get - - -def test__keep_alive(): - assert _keep_alive( - Request(method="GET", target="/", headers=[("Host", "Example.com")]) - ) - assert not _keep_alive( - Request( - method="GET", - target="/", - headers=[("Host", "Example.com"), ("Connection", "close")], - ) - ) - assert not _keep_alive( - Request( - method="GET", - target="/", - headers=[("Host", "Example.com"), ("Connection", "a, b, cLOse, foo")], - ) - ) - assert not _keep_alive( - Request(method="GET", target="/", headers=[], http_version="1.0") - ) - - assert _keep_alive(Response(status_code=200, headers=[])) - assert not _keep_alive(Response(status_code=200, headers=[("Connection", "close")])) - assert not _keep_alive( - Response(status_code=200, headers=[("Connection", "a, b, cLOse, foo")]) - ) - assert not _keep_alive(Response(status_code=200, headers=[], http_version="1.0")) - - -def test__body_framing(): - def headers(cl, te): - headers = [] - if cl is not None: - headers.append(("Content-Length", str(cl))) - if te: - headers.append(("Transfer-Encoding", "chunked")) - return headers - - def resp(status_code=200, cl=None, te=False): - return Response(status_code=status_code, headers=headers(cl, te)) - - def req(cl=None, te=False): - h = headers(cl, te) - h += [("Host", "example.com")] - return Request(method="GET", target="/", headers=h) - - # Special cases where the headers are ignored: - for kwargs in [{}, {"cl": 100}, {"te": True}, {"cl": 100, "te": True}]: - for meth, r in [ - (b"HEAD", resp(**kwargs)), - (b"GET", resp(status_code=204, **kwargs)), - (b"GET", resp(status_code=304, **kwargs)), - ]: - assert _body_framing(meth, r) == ("content-length", (0,)) - - # Transfer-encoding - for kwargs in [{"te": True}, {"cl": 100, "te": True}]: - for meth, r in [(None, req(**kwargs)), (b"GET", resp(**kwargs))]: - assert _body_framing(meth, r) == ("chunked", ()) - - # Content-Length - for meth, r in [(None, req(cl=100)), (b"GET", resp(cl=100))]: - assert _body_framing(meth, r) == ("content-length", (100,)) - - # No headers - assert _body_framing(None, req()) == ("content-length", (0,)) - assert _body_framing(b"GET", resp()) == ("http/1.0", ()) - - -def test_Connection_basics_and_content_length(): - with pytest.raises(ValueError): - Connection("CLIENT") - - p = ConnectionPair() - assert p.conn[CLIENT].our_role is CLIENT - assert p.conn[CLIENT].their_role is SERVER - assert p.conn[SERVER].our_role is SERVER - assert p.conn[SERVER].their_role is CLIENT - - data = p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Content-Length", "10")], - ), - ) - assert data == ( - b"GET / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 10\r\n\r\n" - ) - - for conn in p.conns: - assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - assert p.conn[CLIENT].our_state is SEND_BODY - assert p.conn[CLIENT].their_state is SEND_RESPONSE - assert p.conn[SERVER].our_state is SEND_RESPONSE - assert p.conn[SERVER].their_state is SEND_BODY - - assert p.conn[CLIENT].their_http_version is None - assert p.conn[SERVER].their_http_version == b"1.1" - - data = p.send(SERVER, InformationalResponse(status_code=100, headers=[])) - assert data == b"HTTP/1.1 100 \r\n\r\n" - - data = p.send(SERVER, Response(status_code=200, headers=[("Content-Length", "11")])) - assert data == b"HTTP/1.1 200 \r\nContent-Length: 11\r\n\r\n" - - for conn in p.conns: - assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} - - assert p.conn[CLIENT].their_http_version == b"1.1" - assert p.conn[SERVER].their_http_version == b"1.1" - - data = p.send(CLIENT, Data(data=b"12345")) - assert data == b"12345" - data = p.send( - CLIENT, Data(data=b"67890"), expect=[Data(data=b"67890"), EndOfMessage()] - ) - assert data == b"67890" - data = p.send(CLIENT, EndOfMessage(), expect=[]) - assert data == b"" - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} - - data = p.send(SERVER, Data(data=b"1234567890")) - assert data == b"1234567890" - data = p.send(SERVER, Data(data=b"1"), expect=[Data(data=b"1"), EndOfMessage()]) - assert data == b"1" - data = p.send(SERVER, EndOfMessage(), expect=[]) - assert data == b"" - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - - -def test_chunked(): - p = ConnectionPair() - - p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], - ), - ) - data = p.send(CLIENT, Data(data=b"1234567890", chunk_start=True, chunk_end=True)) - assert data == b"a\r\n1234567890\r\n" - data = p.send(CLIENT, Data(data=b"abcde", chunk_start=True, chunk_end=True)) - assert data == b"5\r\nabcde\r\n" - data = p.send(CLIENT, Data(data=b""), expect=[]) - assert data == b"" - data = p.send(CLIENT, EndOfMessage(headers=[("hello", "there")])) - assert data == b"0\r\nhello: there\r\n\r\n" - - p.send( - SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) - ) - p.send(SERVER, Data(data=b"54321", chunk_start=True, chunk_end=True)) - p.send(SERVER, Data(data=b"12345", chunk_start=True, chunk_end=True)) - p.send(SERVER, EndOfMessage()) - - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - - -def test_chunk_boundaries(): - conn = Connection(our_role=SERVER) - - request = ( - b"POST / HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Transfer-Encoding: chunked\r\n" - b"\r\n" - ) - conn.receive_data(request) - assert conn.next_event() == Request( - method="POST", - target="/", - headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], - ) - assert conn.next_event() is NEED_DATA - - conn.receive_data(b"5\r\nhello\r\n") - assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) - - conn.receive_data(b"5\r\nhel") - assert conn.next_event() == Data(data=b"hel", chunk_start=True, chunk_end=False) - - conn.receive_data(b"l") - assert conn.next_event() == Data(data=b"l", chunk_start=False, chunk_end=False) - - conn.receive_data(b"o\r\n") - assert conn.next_event() == Data(data=b"o", chunk_start=False, chunk_end=True) - - conn.receive_data(b"5\r\nhello") - assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) - - conn.receive_data(b"\r\n") - assert conn.next_event() == NEED_DATA - - conn.receive_data(b"0\r\n\r\n") - assert conn.next_event() == EndOfMessage() - - -def test_client_talking_to_http10_server(): - c = Connection(CLIENT) - c.send(Request(method="GET", target="/", headers=[("Host", "example.com")])) - c.send(EndOfMessage()) - assert c.our_state is DONE - # No content-length, so Http10 framing for body - assert receive_and_get(c, b"HTTP/1.0 200 OK\r\n\r\n") == [ - Response(status_code=200, headers=[], http_version="1.0", reason=b"OK") - ] - assert c.our_state is MUST_CLOSE - assert receive_and_get(c, b"12345") == [Data(data=b"12345")] - assert receive_and_get(c, b"67890") == [Data(data=b"67890")] - assert receive_and_get(c, b"") == [EndOfMessage(), ConnectionClosed()] - assert c.their_state is CLOSED - - -def test_server_talking_to_http10_client(): - c = Connection(SERVER) - # No content-length, so no body - # NB: no host header - assert receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") == [ - Request(method="GET", target="/", headers=[], http_version="1.0"), - EndOfMessage(), - ] - assert c.their_state is MUST_CLOSE - - # We automatically Connection: close back at them - assert ( - c.send(Response(status_code=200, headers=[])) - == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" - ) - - assert c.send(Data(data=b"12345")) == b"12345" - assert c.send(EndOfMessage()) == b"" - assert c.our_state is MUST_CLOSE - - # Check that it works if they do send Content-Length - c = Connection(SERVER) - # NB: no host header - assert receive_and_get(c, b"POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\n1") == [ - Request( - method="POST", - target="/", - headers=[("Content-Length", "10")], - http_version="1.0", - ), - Data(data=b"1"), - ] - assert receive_and_get(c, b"234567890") == [Data(data=b"234567890"), EndOfMessage()] - assert c.their_state is MUST_CLOSE - assert receive_and_get(c, b"") == [ConnectionClosed()] - - -def test_automatic_transfer_encoding_in_response(): - # Check that in responses, the user can specify either Transfer-Encoding: - # chunked or no framing at all, and in both cases we automatically select - # the right option depending on whether the peer speaks HTTP/1.0 or - # HTTP/1.1 - for user_headers in [ - [("Transfer-Encoding", "chunked")], - [], - # In fact, this even works if Content-Length is set, - # because if both are set then Transfer-Encoding wins - [("Transfer-Encoding", "chunked"), ("Content-Length", "100")], - ]: - p = ConnectionPair() - p.send( - CLIENT, - [ - Request(method="GET", target="/", headers=[("Host", "example.com")]), - EndOfMessage(), - ], - ) - # When speaking to HTTP/1.1 client, all of the above cases get - # normalized to Transfer-Encoding: chunked - p.send( - SERVER, - Response(status_code=200, headers=user_headers), - expect=Response( - status_code=200, headers=[("Transfer-Encoding", "chunked")] - ), - ) - - # When speaking to HTTP/1.0 client, all of the above cases get - # normalized to no-framing-headers - c = Connection(SERVER) - receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") - assert ( - c.send(Response(status_code=200, headers=user_headers)) - == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" - ) - assert c.send(Data(data=b"12345")) == b"12345" - - -def test_automagic_connection_close_handling(): - p = ConnectionPair() - # If the user explicitly sets Connection: close, then we notice and - # respect it - p.send( - CLIENT, - [ - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Connection", "close")], - ), - EndOfMessage(), - ], - ) - for conn in p.conns: - assert conn.states[CLIENT] is MUST_CLOSE - # And if the client sets it, the server automatically echoes it back - p.send( - SERVER, - # no header here... - [Response(status_code=204, headers=[]), EndOfMessage()], - # ...but oh look, it arrived anyway - expect=[ - Response(status_code=204, headers=[("connection", "close")]), - EndOfMessage(), - ], - ) - for conn in p.conns: - assert conn.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} - - -def test_100_continue(): - def setup(): - p = ConnectionPair() - p.send( - CLIENT, - Request( - method="GET", - target="/", - headers=[ - ("Host", "example.com"), - ("Content-Length", "100"), - ("Expect", "100-continue"), - ], - ), - ) - for conn in p.conns: - assert conn.client_is_waiting_for_100_continue - assert not p.conn[CLIENT].they_are_waiting_for_100_continue - assert p.conn[SERVER].they_are_waiting_for_100_continue - return p - - # Disabled by 100 Continue - p = setup() - p.send(SERVER, InformationalResponse(status_code=100, headers=[])) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - # Disabled by a real response - p = setup() - p.send( - SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) - ) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - # Disabled by the client going ahead and sending stuff anyway - p = setup() - p.send(CLIENT, Data(data=b"12345")) - for conn in p.conns: - assert not conn.client_is_waiting_for_100_continue - assert not conn.they_are_waiting_for_100_continue - - -def test_max_incomplete_event_size_countermeasure(): - # Infinitely long headers are definitely not okay - c = Connection(SERVER) - c.receive_data(b"GET / HTTP/1.0\r\nEndless: ") - assert c.next_event() is NEED_DATA - with pytest.raises(RemoteProtocolError): - while True: - c.receive_data(b"a" * 1024) - c.next_event() - - # Checking that the same header is accepted / rejected depending on the - # max_incomplete_event_size setting: - c = Connection(SERVER, max_incomplete_event_size=5000) - c.receive_data(b"GET / HTTP/1.0\r\nBig: ") - c.receive_data(b"a" * 4000) - c.receive_data(b"\r\n\r\n") - assert get_all_events(c) == [ - Request( - method="GET", target="/", http_version="1.0", headers=[("big", "a" * 4000)] - ), - EndOfMessage(), - ] - - c = Connection(SERVER, max_incomplete_event_size=4000) - c.receive_data(b"GET / HTTP/1.0\r\nBig: ") - c.receive_data(b"a" * 4000) - with pytest.raises(RemoteProtocolError): - c.next_event() - - # Temporarily exceeding the size limit is fine, as long as its done with - # complete events: - c = Connection(SERVER, max_incomplete_event_size=5000) - c.receive_data(b"GET / HTTP/1.0\r\nContent-Length: 10000") - c.receive_data(b"\r\n\r\n" + b"a" * 10000) - assert get_all_events(c) == [ - Request( - method="GET", - target="/", - http_version="1.0", - headers=[("Content-Length", "10000")], - ), - Data(data=b"a" * 10000), - EndOfMessage(), - ] - - c = Connection(SERVER, max_incomplete_event_size=100) - # Two pipelined requests to create a way-too-big receive buffer... but - # it's fine because we're not checking - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a\r\n\r\n" - b"GET /2 HTTP/1.1\r\nHost: b\r\n\r\n" + b"X" * 1000 - ) - assert get_all_events(c) == [ - Request(method="GET", target="/1", headers=[("host", "a")]), - EndOfMessage(), - ] - # Even more data comes in, still no problem - c.receive_data(b"X" * 1000) - # We can respond and reuse to get the second pipelined request - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - assert get_all_events(c) == [ - Request(method="GET", target="/2", headers=[("host", "b")]), - EndOfMessage(), - ] - # But once we unpause and try to read the next message, and find that it's - # incomplete and the buffer is *still* way too large, then *that's* a - # problem: - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - with pytest.raises(RemoteProtocolError): - c.next_event() - - -def test_reuse_simple(): - p = ConnectionPair() - p.send( - CLIENT, - [Request(method="GET", target="/", headers=[("Host", "a")]), EndOfMessage()], - ) - p.send(SERVER, [Response(status_code=200, headers=[]), EndOfMessage()]) - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: DONE} - conn.start_next_cycle() - - p.send( - CLIENT, - [ - Request(method="DELETE", target="/foo", headers=[("Host", "a")]), - EndOfMessage(), - ], - ) - p.send(SERVER, [Response(status_code=404, headers=[]), EndOfMessage()]) - - -def test_pipelining(): - # Client doesn't support pipelining, so we have to do this by hand - c = Connection(SERVER) - assert c.next_event() is NEED_DATA - # 3 requests all bunched up - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"12345" - b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"67890" - b"GET /3 HTTP/1.1\r\nHost: a.com\r\n\r\n" - ) - assert get_all_events(c) == [ - Request( - method="GET", - target="/1", - headers=[("Host", "a.com"), ("Content-Length", "5")], - ), - Data(data=b"12345"), - EndOfMessage(), - ] - assert c.their_state is DONE - assert c.our_state is SEND_RESPONSE - - assert c.next_event() is PAUSED - - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.their_state is DONE - assert c.our_state is DONE - - c.start_next_cycle() - - assert get_all_events(c) == [ - Request( - method="GET", - target="/2", - headers=[("Host", "a.com"), ("Content-Length", "5")], - ), - Data(data=b"67890"), - EndOfMessage(), - ] - assert c.next_event() is PAUSED - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - c.start_next_cycle() - - assert get_all_events(c) == [ - Request(method="GET", target="/3", headers=[("Host", "a.com")]), - EndOfMessage(), - ] - # Doesn't pause this time, no trailing data - assert c.next_event() is NEED_DATA - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - - # Arrival of more data triggers pause - assert c.next_event() is NEED_DATA - c.receive_data(b"SADF") - assert c.next_event() is PAUSED - assert c.trailing_data == (b"SADF", False) - # If EOF arrives while paused, we don't see that either: - c.receive_data(b"") - assert c.trailing_data == (b"SADF", True) - assert c.next_event() is PAUSED - c.receive_data(b"") - assert c.next_event() is PAUSED - # Can't call receive_data with non-empty buf after closing it - with pytest.raises(RuntimeError): - c.receive_data(b"FDSA") - - -def test_protocol_switch(): - for (req, deny, accept) in [ - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1")], - ), - Response(status_code=404, headers=[]), - Response(status_code=200, headers=[]), - ), - ( - Request( - method="GET", - target="/", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=200, headers=[]), - InformationalResponse(status_code=101, headers=[("Upgrade", "a")]), - ), - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=404, headers=[]), - # Accept CONNECT, not upgrade - Response(status_code=200, headers=[]), - ), - ( - Request( - method="CONNECT", - target="example.com:443", - headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], - ), - Response(status_code=404, headers=[]), - # Accept Upgrade, not CONNECT - InformationalResponse(status_code=101, headers=[("Upgrade", "b")]), - ), - ]: - - def setup(): - p = ConnectionPair() - p.send(CLIENT, req) - # No switch-related state change stuff yet; the client has to - # finish the request before that kicks in - for conn in p.conns: - assert conn.states[CLIENT] is SEND_BODY - p.send(CLIENT, [Data(data=b"1"), EndOfMessage()]) - for conn in p.conns: - assert conn.states[CLIENT] is MIGHT_SWITCH_PROTOCOL - assert p.conn[SERVER].next_event() is PAUSED - return p - - # Test deny case - p = setup() - p.send(SERVER, deny) - for conn in p.conns: - assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} - p.send(SERVER, EndOfMessage()) - # Check that re-use is still allowed after a denial - for conn in p.conns: - conn.start_next_cycle() - - # Test accept case - p = setup() - p.send(SERVER, accept) - for conn in p.conns: - assert conn.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - conn.receive_data(b"123") - assert conn.next_event() is PAUSED - conn.receive_data(b"456") - assert conn.next_event() is PAUSED - assert conn.trailing_data == (b"123456", False) - - # Pausing in might-switch, then recovery - # (weird artificial case where the trailing data actually is valid - # HTTP for some reason, because this makes it easier to test the state - # logic) - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"GET / HTTP/1.0\r\n\r\n") - assert sc.next_event() is PAUSED - assert sc.trailing_data == (b"GET / HTTP/1.0\r\n\r\n", False) - sc.send(deny) - assert sc.next_event() is PAUSED - sc.send(EndOfMessage()) - sc.start_next_cycle() - assert get_all_events(sc) == [ - Request(method="GET", target="/", headers=[], http_version="1.0"), - EndOfMessage(), - ] - - # When we're DONE, have no trailing data, and the connection gets - # closed, we report ConnectionClosed(). When we're in might-switch or - # switched, we don't. - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"") - assert sc.next_event() is PAUSED - assert sc.trailing_data == (b"", True) - p.send(SERVER, accept) - assert sc.next_event() is PAUSED - - p = setup() - sc = p.conn[SERVER] - sc.receive_data(b"") == [] - assert sc.next_event() is PAUSED - sc.send(deny) - assert sc.next_event() == ConnectionClosed() - - # You can't send after switching protocols, or while waiting for a - # protocol switch - p = setup() - with pytest.raises(LocalProtocolError): - p.conn[CLIENT].send( - Request(method="GET", target="/", headers=[("Host", "a")]) - ) - p = setup() - p.send(SERVER, accept) - with pytest.raises(LocalProtocolError): - p.conn[SERVER].send(Data(data=b"123")) - - -def test_close_simple(): - # Just immediately closing a new connection without anything having - # happened yet. - for (who_shot_first, who_shot_second) in [(CLIENT, SERVER), (SERVER, CLIENT)]: - - def setup(): - p = ConnectionPair() - p.send(who_shot_first, ConnectionClosed()) - for conn in p.conns: - assert conn.states == { - who_shot_first: CLOSED, - who_shot_second: MUST_CLOSE, - } - return p - - # You can keep putting b"" into a closed connection, and you keep - # getting ConnectionClosed() out: - p = setup() - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - p.conn[who_shot_second].receive_data(b"") - assert p.conn[who_shot_second].next_event() == ConnectionClosed() - # Second party can close... - p = setup() - p.send(who_shot_second, ConnectionClosed()) - for conn in p.conns: - assert conn.our_state is CLOSED - assert conn.their_state is CLOSED - # But trying to receive new data on a closed connection is a - # RuntimeError (not ProtocolError, because the problem here isn't - # violation of HTTP, it's violation of physics) - p = setup() - with pytest.raises(RuntimeError): - p.conn[who_shot_second].receive_data(b"123") - # And receiving new data on a MUST_CLOSE connection is a ProtocolError - p = setup() - p.conn[who_shot_first].receive_data(b"GET") - with pytest.raises(RemoteProtocolError): - p.conn[who_shot_first].next_event() - - -def test_close_different_states(): - req = [ - Request(method="GET", target="/foo", headers=[("Host", "a")]), - EndOfMessage(), - ] - resp = [Response(status_code=200, headers=[]), EndOfMessage()] - - # Client before request - p = ConnectionPair() - p.send(CLIENT, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} - - # Client after request - p = ConnectionPair() - p.send(CLIENT, req) - p.send(CLIENT, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} - - # Server after request -> not allowed - p = ConnectionPair() - p.send(CLIENT, req) - with pytest.raises(LocalProtocolError): - p.conn[SERVER].send(ConnectionClosed()) - p.conn[CLIENT].receive_data(b"") - with pytest.raises(RemoteProtocolError): - p.conn[CLIENT].next_event() - - # Server after response - p = ConnectionPair() - p.send(CLIENT, req) - p.send(SERVER, resp) - p.send(SERVER, ConnectionClosed()) - for conn in p.conns: - assert conn.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} - - # Both after closing (ConnectionClosed() is idempotent) - p = ConnectionPair() - p.send(CLIENT, req) - p.send(SERVER, resp) - p.send(CLIENT, ConnectionClosed()) - p.send(SERVER, ConnectionClosed()) - p.send(CLIENT, ConnectionClosed()) - p.send(SERVER, ConnectionClosed()) - - # In the middle of sending -> not allowed - p = ConnectionPair() - p.send( - CLIENT, - Request( - method="GET", target="/", headers=[("Host", "a"), ("Content-Length", "10")] - ), - ) - with pytest.raises(LocalProtocolError): - p.conn[CLIENT].send(ConnectionClosed()) - p.conn[SERVER].receive_data(b"") - with pytest.raises(RemoteProtocolError): - p.conn[SERVER].next_event() - - -# Receive several requests and then client shuts down their side of the -# connection; we can respond to each -def test_pipelined_close(): - c = Connection(SERVER) - # 2 requests then a close - c.receive_data( - b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"12345" - b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" - b"67890" - ) - c.receive_data(b"") - assert get_all_events(c) == [ - Request( - method="GET", - target="/1", - headers=[("host", "a.com"), ("content-length", "5")], - ), - Data(data=b"12345"), - EndOfMessage(), - ] - assert c.states[CLIENT] is DONE - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.states[SERVER] is DONE - c.start_next_cycle() - assert get_all_events(c) == [ - Request( - method="GET", - target="/2", - headers=[("host", "a.com"), ("content-length", "5")], - ), - Data(data=b"67890"), - EndOfMessage(), - ConnectionClosed(), - ] - assert c.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} - c.send(Response(status_code=200, headers=[])) - c.send(EndOfMessage()) - assert c.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} - c.send(ConnectionClosed()) - assert c.states == {CLIENT: CLOSED, SERVER: CLOSED} - - -def test_sendfile(): - class SendfilePlaceholder: - def __len__(self): - return 10 - - placeholder = SendfilePlaceholder() - - def setup(header, http_version): - c = Connection(SERVER) - receive_and_get( - c, "GET / HTTP/{}\r\nHost: a\r\n\r\n".format(http_version).encode("ascii") - ) - headers = [] - if header: - headers.append(header) - c.send(Response(status_code=200, headers=headers)) - return c, c.send_with_data_passthrough(Data(data=placeholder)) - - c, data = setup(("Content-Length", "10"), "1.1") - assert data == [placeholder] - # Raises an error if the connection object doesn't think we've sent - # exactly 10 bytes - c.send(EndOfMessage()) - - _, data = setup(("Transfer-Encoding", "chunked"), "1.1") - assert placeholder in data - data[data.index(placeholder)] = b"x" * 10 - assert b"".join(data) == b"a\r\nxxxxxxxxxx\r\n" - - c, data = setup(None, "1.0") - assert data == [placeholder] - assert c.our_state is SEND_BODY - - -def test_errors(): - # After a receive error, you can't receive - for role in [CLIENT, SERVER]: - c = Connection(our_role=role) - c.receive_data(b"gibberish\r\n\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - # Now any attempt to receive continues to raise - assert c.their_state is ERROR - assert c.our_state is not ERROR - print(c._cstate.states) - with pytest.raises(RemoteProtocolError): - c.next_event() - # But we can still yell at the client for sending us gibberish - if role is SERVER: - assert ( - c.send(Response(status_code=400, headers=[])) - == b"HTTP/1.1 400 \r\nConnection: close\r\n\r\n" - ) - - # After an error sending, you can no longer send - # (This is especially important for things like content-length errors, - # where there's complex internal state being modified) - def conn(role): - c = Connection(our_role=role) - if role is SERVER: - # Put it into the state where it *could* send a response... - receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") - assert c.our_state is SEND_RESPONSE - return c - - for role in [CLIENT, SERVER]: - if role is CLIENT: - # This HTTP/1.0 request won't be detected as bad until after we go - # through the state machine and hit the writing code - good = Request(method="GET", target="/", headers=[("Host", "example.com")]) - bad = Request( - method="GET", - target="/", - headers=[("Host", "example.com")], - http_version="1.0", - ) - elif role is SERVER: - good = Response(status_code=200, headers=[]) - bad = Response(status_code=200, headers=[], http_version="1.0") - # Make sure 'good' actually is good - c = conn(role) - c.send(good) - assert c.our_state is not ERROR - # Do that again, but this time sending 'bad' first - c = conn(role) - with pytest.raises(LocalProtocolError): - c.send(bad) - assert c.our_state is ERROR - assert c.their_state is not ERROR - # Now 'good' is not so good - with pytest.raises(LocalProtocolError): - c.send(good) - - # And check send_failed() too - c = conn(role) - c.send_failed() - assert c.our_state is ERROR - assert c.their_state is not ERROR - # This is idempotent - c.send_failed() - assert c.our_state is ERROR - assert c.their_state is not ERROR - - -def test_idle_receive_nothing(): - # At one point this incorrectly raised an error - for role in [CLIENT, SERVER]: - c = Connection(role) - assert c.next_event() is NEED_DATA - - -def test_connection_drop(): - c = Connection(SERVER) - c.receive_data(b"GET /") - assert c.next_event() is NEED_DATA - c.receive_data(b"") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -def test_408_request_timeout(): - # Should be able to send this spontaneously as a server without seeing - # anything from client - p = ConnectionPair() - p.send(SERVER, Response(status_code=408, headers=[])) - - -# This used to raise IndexError -def test_empty_request(): - c = Connection(SERVER) - c.receive_data(b"\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -# This used to raise IndexError -def test_empty_response(): - c = Connection(CLIENT) - c.send(Request(method="GET", target="/", headers=[("Host", "a")])) - c.receive_data(b"\r\n") - with pytest.raises(RemoteProtocolError): - c.next_event() - - -# This used to give different headers for HEAD and GET. -# The correct way to handle HEAD is to put whatever headers we *would* have -# put if it were a GET -- even though we know that for HEAD, those headers -# will be ignored. -def test_HEAD_framing_headers(): - def setup(method, http_version): - c = Connection(SERVER) - c.receive_data( - method + b" / HTTP/" + http_version + b"\r\n" + b"Host: example.com\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert type(c.next_event()) is EndOfMessage - return c - - for method in [b"GET", b"HEAD"]: - # No Content-Length, HTTP/1.1 peer, should use chunked - c = setup(method, b"1.1") - assert ( - c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - - # No Content-Length, HTTP/1.0 peer, frame with connection: close - c = setup(method, b"1.0") - assert ( - c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" - b"Connection: close\r\n\r\n" - ) - - # Content-Length + Transfer-Encoding, TE wins - c = setup(method, b"1.1") - assert ( - c.send( - Response( - status_code=200, - headers=[ - ("Content-Length", "100"), - ("Transfer-Encoding", "chunked"), - ], - ) - ) - == b"HTTP/1.1 200 \r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - - -def test_special_exceptions_for_lost_connection_in_message_body(): - c = Connection(SERVER) - c.receive_data( - b"POST / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 100\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert c.next_event() is NEED_DATA - c.receive_data(b"12345") - assert c.next_event() == Data(data=b"12345") - c.receive_data(b"") - with pytest.raises(RemoteProtocolError) as excinfo: - c.next_event() - assert "received 5 bytes" in str(excinfo.value) - assert "expected 100" in str(excinfo.value) - - c = Connection(SERVER) - c.receive_data( - b"POST / HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Transfer-Encoding: chunked\r\n\r\n" - ) - assert type(c.next_event()) is Request - assert c.next_event() is NEED_DATA - c.receive_data(b"8\r\n012345") - assert c.next_event().data == b"012345" - c.receive_data(b"") - with pytest.raises(RemoteProtocolError) as excinfo: - c.next_event() - assert "incomplete chunked read" in str(excinfo.value) diff --git a/env/lib/python3.8/site-packages/h11/tests/test_events.py b/env/lib/python3.8/site-packages/h11/tests/test_events.py deleted file mode 100644 index 07ffc131..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_events.py +++ /dev/null @@ -1,181 +0,0 @@ -import pytest - -from .. import _events -from .._events import * -from .._util import LocalProtocolError - - -def test_event_bundle(): - class T(_events._EventBundle): - _fields = ["a", "b"] - _defaults = {"b": 1} - - def _validate(self): - if self.a == 0: - raise ValueError - - # basic construction and methods - t = T(a=1, b=0) - assert repr(t) == "T(a=1, b=0)" - assert t == T(a=1, b=0) - assert not (t == T(a=2, b=0)) - assert not (t != T(a=1, b=0)) - assert t != T(a=2, b=0) - with pytest.raises(TypeError): - hash(t) - - # check defaults - t = T(a=10) - assert t.a == 10 - assert t.b == 1 - - # no positional args - with pytest.raises(TypeError): - T(1) - - with pytest.raises(TypeError): - T(1, a=1, b=0) - - # unknown field - with pytest.raises(TypeError): - T(a=1, b=0, c=10) - - # missing required field - with pytest.raises(TypeError) as exc: - T(b=0) - # make sure we error on the right missing kwarg - assert "kwarg a" in str(exc.value) - - # _validate is called - with pytest.raises(ValueError): - T(a=0, b=0) - - -def test_events(): - with pytest.raises(LocalProtocolError): - # Missing Host: - req = Request( - method="GET", target="/", headers=[("a", "b")], http_version="1.1" - ) - # But this is okay (HTTP/1.0) - req = Request(method="GET", target="/", headers=[("a", "b")], http_version="1.0") - # fields are normalized - assert req.method == b"GET" - assert req.target == b"/" - assert req.headers == [(b"a", b"b")] - assert req.http_version == b"1.0" - - # This is also okay -- has a Host (with weird capitalization, which is ok) - req = Request( - method="GET", - target="/", - headers=[("a", "b"), ("hOSt", "example.com")], - http_version="1.1", - ) - # we normalize header capitalization - assert req.headers == [(b"a", b"b"), (b"host", b"example.com")] - - # Multiple host is bad too - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Host", "a")], - http_version="1.1", - ) - # Even for HTTP/1.0 - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Host", "a")], - http_version="1.0", - ) - - # Header values are validated - for bad_char in "\x00\r\n\f\v": - with pytest.raises(LocalProtocolError): - req = Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Foo", "asd" + bad_char)], - http_version="1.0", - ) - - # But for compatibility we allow non-whitespace control characters, even - # though they're forbidden by the spec. - Request( - method="GET", - target="/", - headers=[("Host", "a"), ("Foo", "asd\x01\x02\x7f")], - http_version="1.0", - ) - - # Request target is validated - for bad_char in b"\x00\x20\x7f\xee": - target = bytearray(b"/") - target.append(bad_char) - with pytest.raises(LocalProtocolError): - Request( - method="GET", target=target, headers=[("Host", "a")], http_version="1.1" - ) - - ir = InformationalResponse(status_code=100, headers=[("Host", "a")]) - assert ir.status_code == 100 - assert ir.headers == [(b"host", b"a")] - assert ir.http_version == b"1.1" - - with pytest.raises(LocalProtocolError): - InformationalResponse(status_code=200, headers=[("Host", "a")]) - - resp = Response(status_code=204, headers=[], http_version="1.0") - assert resp.status_code == 204 - assert resp.headers == [] - assert resp.http_version == b"1.0" - - with pytest.raises(LocalProtocolError): - resp = Response(status_code=100, headers=[], http_version="1.0") - - with pytest.raises(LocalProtocolError): - Response(status_code="100", headers=[], http_version="1.0") - - with pytest.raises(LocalProtocolError): - InformationalResponse(status_code=b"100", headers=[], http_version="1.0") - - d = Data(data=b"asdf") - assert d.data == b"asdf" - - eom = EndOfMessage() - assert eom.headers == [] - - cc = ConnectionClosed() - assert repr(cc) == "ConnectionClosed()" - - -def test_intenum_status_code(): - # https://github.com/python-hyper/h11/issues/72 - try: - from http import HTTPStatus - except ImportError: - pytest.skip("Only affects Python 3") - - r = Response(status_code=HTTPStatus.OK, headers=[], http_version="1.0") - assert r.status_code == HTTPStatus.OK - assert type(r.status_code) is not type(HTTPStatus.OK) - assert type(r.status_code) is int - - -def test_header_casing(): - r = Request( - method="GET", - target="/", - headers=[("Host", "example.org"), ("Connection", "keep-alive")], - http_version="1.1", - ) - assert len(r.headers) == 2 - assert r.headers[0] == (b"host", b"example.org") - assert r.headers == [(b"host", b"example.org"), (b"connection", b"keep-alive")] - assert r.headers.raw_items() == [ - (b"Host", b"example.org"), - (b"Connection", b"keep-alive"), - ] diff --git a/env/lib/python3.8/site-packages/h11/tests/test_headers.py b/env/lib/python3.8/site-packages/h11/tests/test_headers.py deleted file mode 100644 index ff3dc8d7..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_headers.py +++ /dev/null @@ -1,151 +0,0 @@ -import pytest - -from .._headers import * - - -def test_normalize_and_validate(): - assert normalize_and_validate([("foo", "bar")]) == [(b"foo", b"bar")] - assert normalize_and_validate([(b"foo", b"bar")]) == [(b"foo", b"bar")] - - # no leading/trailing whitespace in names - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo ", "bar")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b" foo", "bar")]) - - # no weird characters in names - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([(b"foo bar", b"baz")]) - assert "foo bar" in str(excinfo.value) - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\x00bar", b"baz")]) - # Not even 8-bit characters: - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\xffbar", b"baz")]) - # And not even the control characters we allow in values: - with pytest.raises(LocalProtocolError): - normalize_and_validate([(b"foo\x01bar", b"baz")]) - - # no return or NUL characters in values - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([("foo", "bar\rbaz")]) - assert "bar\\rbaz" in str(excinfo.value) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "bar\nbaz")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "bar\x00baz")]) - # no leading/trailing whitespace - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "barbaz ")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", " barbaz")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "barbaz\t")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("foo", "\tbarbaz")]) - - # content-length - assert normalize_and_validate([("Content-Length", "1")]) == [ - (b"content-length", b"1") - ] - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "asdf")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1x")]) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1"), ("Content-Length", "2")]) - assert normalize_and_validate( - [("Content-Length", "0"), ("Content-Length", "0")] - ) == [(b"content-length", b"0")] - assert normalize_and_validate([("Content-Length", "0 , 0")]) == [ - (b"content-length", b"0") - ] - with pytest.raises(LocalProtocolError): - normalize_and_validate( - [("Content-Length", "1"), ("Content-Length", "1"), ("Content-Length", "2")] - ) - with pytest.raises(LocalProtocolError): - normalize_and_validate([("Content-Length", "1 , 1,2")]) - - # transfer-encoding - assert normalize_and_validate([("Transfer-Encoding", "chunked")]) == [ - (b"transfer-encoding", b"chunked") - ] - assert normalize_and_validate([("Transfer-Encoding", "cHuNkEd")]) == [ - (b"transfer-encoding", b"chunked") - ] - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate([("Transfer-Encoding", "gzip")]) - assert excinfo.value.error_status_hint == 501 # Not Implemented - with pytest.raises(LocalProtocolError) as excinfo: - normalize_and_validate( - [("Transfer-Encoding", "chunked"), ("Transfer-Encoding", "gzip")] - ) - assert excinfo.value.error_status_hint == 501 # Not Implemented - - -def test_get_set_comma_header(): - headers = normalize_and_validate( - [ - ("Connection", "close"), - ("whatever", "something"), - ("connectiON", "fOo,, , BAR"), - ] - ) - - assert get_comma_header(headers, b"connection") == [b"close", b"foo", b"bar"] - - headers = set_comma_header(headers, b"newthing", ["a", "b"]) - - with pytest.raises(LocalProtocolError): - set_comma_header(headers, b"newthing", [" a", "b"]) - - assert headers == [ - (b"connection", b"close"), - (b"whatever", b"something"), - (b"connection", b"fOo,, , BAR"), - (b"newthing", b"a"), - (b"newthing", b"b"), - ] - - headers = set_comma_header(headers, b"whatever", ["different thing"]) - - assert headers == [ - (b"connection", b"close"), - (b"connection", b"fOo,, , BAR"), - (b"newthing", b"a"), - (b"newthing", b"b"), - (b"whatever", b"different thing"), - ] - - -def test_has_100_continue(): - from .._events import Request - - assert has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-continue")], - ) - ) - assert not has_expect_100_continue( - Request(method="GET", target="/", headers=[("Host", "example.com")]) - ) - # Case insensitive - assert has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-Continue")], - ) - ) - # Doesn't work in HTTP/1.0 - assert not has_expect_100_continue( - Request( - method="GET", - target="/", - headers=[("Host", "example.com"), ("Expect", "100-continue")], - http_version="1.0", - ) - ) diff --git a/env/lib/python3.8/site-packages/h11/tests/test_helpers.py b/env/lib/python3.8/site-packages/h11/tests/test_helpers.py deleted file mode 100644 index 1477947a..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_helpers.py +++ /dev/null @@ -1,23 +0,0 @@ -from .helpers import * - - -def test_normalize_data_events(): - assert normalize_data_events( - [ - Data(data=bytearray(b"1")), - Data(data=b"2"), - Response(status_code=200, headers=[]), - Data(data=b"3"), - Data(data=b"4"), - EndOfMessage(), - Data(data=b"5"), - Data(data=b"6"), - Data(data=b"7"), - ] - ) == [ - Data(data=b"12"), - Response(status_code=200, headers=[]), - Data(data=b"34"), - EndOfMessage(), - Data(data=b"567"), - ] diff --git a/env/lib/python3.8/site-packages/h11/tests/test_io.py b/env/lib/python3.8/site-packages/h11/tests/test_io.py deleted file mode 100644 index 0323b269..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_io.py +++ /dev/null @@ -1,507 +0,0 @@ -import pytest - -from .._events import * -from .._headers import Headers, normalize_and_validate -from .._readers import ( - _obsolete_line_fold, - ChunkedReader, - ContentLengthReader, - Http10Reader, - READERS, -) -from .._receivebuffer import ReceiveBuffer -from .._state import * -from .._util import LocalProtocolError -from .._writers import ( - ChunkedWriter, - ContentLengthWriter, - Http10Writer, - write_any_response, - write_headers, - write_request, - WRITERS, -) -from .helpers import normalize_data_events - -SIMPLE_CASES = [ - ( - (CLIENT, IDLE), - Request( - method="GET", - target="/a", - headers=[("Host", "foo"), ("Connection", "close")], - ), - b"GET /a HTTP/1.1\r\nHost: foo\r\nConnection: close\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - Response(status_code=200, headers=[("Connection", "close")], reason=b"OK"), - b"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - Response(status_code=200, headers=[], reason=b"OK"), - b"HTTP/1.1 200 OK\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - InformationalResponse( - status_code=101, headers=[("Upgrade", "websocket")], reason=b"Upgrade" - ), - b"HTTP/1.1 101 Upgrade\r\nUpgrade: websocket\r\n\r\n", - ), - ( - (SERVER, SEND_RESPONSE), - InformationalResponse(status_code=101, headers=[], reason=b"Upgrade"), - b"HTTP/1.1 101 Upgrade\r\n\r\n", - ), -] - - -def dowrite(writer, obj): - got_list = [] - writer(obj, got_list.append) - return b"".join(got_list) - - -def tw(writer, obj, expected): - got = dowrite(writer, obj) - assert got == expected - - -def makebuf(data): - buf = ReceiveBuffer() - buf += data - return buf - - -def tr(reader, data, expected): - def check(got): - assert got == expected - # Headers should always be returned as bytes, not e.g. bytearray - # https://github.com/python-hyper/wsproto/pull/54#issuecomment-377709478 - for name, value in getattr(got, "headers", []): - print(name, value) - assert type(name) is bytes - assert type(value) is bytes - - # Simple: consume whole thing - buf = makebuf(data) - check(reader(buf)) - assert not buf - - # Incrementally growing buffer - buf = ReceiveBuffer() - for i in range(len(data)): - assert reader(buf) is None - buf += data[i : i + 1] - check(reader(buf)) - - # Trailing data - buf = makebuf(data) - buf += b"trailing" - check(reader(buf)) - assert bytes(buf) == b"trailing" - - -def test_writers_simple(): - for ((role, state), event, binary) in SIMPLE_CASES: - tw(WRITERS[role, state], event, binary) - - -def test_readers_simple(): - for ((role, state), event, binary) in SIMPLE_CASES: - tr(READERS[role, state], binary, event) - - -def test_writers_unusual(): - # Simple test of the write_headers utility routine - tw( - write_headers, - normalize_and_validate([("foo", "bar"), ("baz", "quux")]), - b"foo: bar\r\nbaz: quux\r\n\r\n", - ) - tw(write_headers, Headers([]), b"\r\n") - - # We understand HTTP/1.0, but we don't speak it - with pytest.raises(LocalProtocolError): - tw( - write_request, - Request( - method="GET", - target="/", - headers=[("Host", "foo"), ("Connection", "close")], - http_version="1.0", - ), - None, - ) - with pytest.raises(LocalProtocolError): - tw( - write_any_response, - Response( - status_code=200, headers=[("Connection", "close")], http_version="1.0" - ), - None, - ) - - -def test_readers_unusual(): - # Reading HTTP/1.0 - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.0\r\nSome: header\r\n\r\n", - Request( - method="HEAD", - target="/foo", - headers=[("Some", "header")], - http_version="1.0", - ), - ) - - # check no-headers, since it's only legal with HTTP/1.0 - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.0\r\n\r\n", - Request(method="HEAD", target="/foo", headers=[], http_version="1.0"), - ) - - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\nSome: header\r\n\r\n", - Response( - status_code=200, - headers=[("Some", "header")], - http_version="1.0", - reason=b"OK", - ), - ) - - # single-character header values (actually disallowed by the ABNF in RFC - # 7230 -- this is a bug in the standard that we originally copied...) - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo: a a a a a \r\n\r\n", - Response( - status_code=200, - headers=[("Foo", "a a a a a")], - http_version="1.0", - reason=b"OK", - ), - ) - - # Empty headers -- also legal - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo:\r\n\r\n", - Response( - status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" - ), - ) - - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200 OK\r\n" b"Foo: \t \t \r\n\r\n", - Response( - status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" - ), - ) - - # Tolerate broken servers that leave off the response code - tr( - READERS[SERVER, SEND_RESPONSE], - b"HTTP/1.0 200\r\n" b"Foo: bar\r\n\r\n", - Response( - status_code=200, headers=[("Foo", "bar")], http_version="1.0", reason=b"" - ), - ) - - # obsolete line folding - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" - b"Host: example.com\r\n" - b"Some: multi-line\r\n" - b" header\r\n" - b"\tnonsense\r\n" - b" \t \t\tI guess\r\n" - b"Connection: close\r\n" - b"More-nonsense: in the\r\n" - b" last header \r\n\r\n", - Request( - method="HEAD", - target="/foo", - headers=[ - ("Host", "example.com"), - ("Some", "multi-line header nonsense I guess"), - ("Connection", "close"), - ("More-nonsense", "in the last header"), - ], - ), - ) - - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b" folded: line\r\n\r\n", - None, - ) - - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo : line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", - None, - ) - with pytest.raises(LocalProtocolError): - tr(READERS[CLIENT, IDLE], b"HEAD /foo HTTP/1.1\r\n" b": line\r\n\r\n", None) - - -def test__obsolete_line_fold_bytes(): - # _obsolete_line_fold has a defensive cast to bytearray, which is - # necessary to protect against O(n^2) behavior in case anyone ever passes - # in regular bytestrings... but right now we never pass in regular - # bytestrings. so this test just exists to get some coverage on that - # defensive cast. - assert list(_obsolete_line_fold([b"aaa", b"bbb", b" ccc", b"ddd"])) == [ - b"aaa", - bytearray(b"bbb ccc"), - b"ddd", - ] - - -def _run_reader_iter(reader, buf, do_eof): - while True: - event = reader(buf) - if event is None: - break - yield event - # body readers have undefined behavior after returning EndOfMessage, - # because this changes the state so they don't get called again - if type(event) is EndOfMessage: - break - if do_eof: - assert not buf - yield reader.read_eof() - - -def _run_reader(*args): - events = list(_run_reader_iter(*args)) - return normalize_data_events(events) - - -def t_body_reader(thunk, data, expected, do_eof=False): - # Simple: consume whole thing - print("Test 1") - buf = makebuf(data) - assert _run_reader(thunk(), buf, do_eof) == expected - - # Incrementally growing buffer - print("Test 2") - reader = thunk() - buf = ReceiveBuffer() - events = [] - for i in range(len(data)): - events += _run_reader(reader, buf, False) - buf += data[i : i + 1] - events += _run_reader(reader, buf, do_eof) - assert normalize_data_events(events) == expected - - is_complete = any(type(event) is EndOfMessage for event in expected) - if is_complete and not do_eof: - buf = makebuf(data + b"trailing") - assert _run_reader(thunk(), buf, False) == expected - - -def test_ContentLengthReader(): - t_body_reader(lambda: ContentLengthReader(0), b"", [EndOfMessage()]) - - t_body_reader( - lambda: ContentLengthReader(10), - b"0123456789", - [Data(data=b"0123456789"), EndOfMessage()], - ) - - -def test_Http10Reader(): - t_body_reader(Http10Reader, b"", [EndOfMessage()], do_eof=True) - t_body_reader(Http10Reader, b"asdf", [Data(data=b"asdf")], do_eof=False) - t_body_reader( - Http10Reader, b"asdf", [Data(data=b"asdf"), EndOfMessage()], do_eof=True - ) - - -def test_ChunkedReader(): - t_body_reader(ChunkedReader, b"0\r\n\r\n", [EndOfMessage()]) - - t_body_reader( - ChunkedReader, - b"0\r\nSome: header\r\n\r\n", - [EndOfMessage(headers=[("Some", "header")])], - ) - - t_body_reader( - ChunkedReader, - b"5\r\n01234\r\n" - + b"10\r\n0123456789abcdef\r\n" - + b"0\r\n" - + b"Some: header\r\n\r\n", - [ - Data(data=b"012340123456789abcdef"), - EndOfMessage(headers=[("Some", "header")]), - ], - ) - - t_body_reader( - ChunkedReader, - b"5\r\n01234\r\n" + b"10\r\n0123456789abcdef\r\n" + b"0\r\n\r\n", - [Data(data=b"012340123456789abcdef"), EndOfMessage()], - ) - - # handles upper and lowercase hex - t_body_reader( - ChunkedReader, - b"aA\r\n" + b"x" * 0xAA + b"\r\n" + b"0\r\n\r\n", - [Data(data=b"x" * 0xAA), EndOfMessage()], - ) - - # refuses arbitrarily long chunk integers - with pytest.raises(LocalProtocolError): - # Technically this is legal HTTP/1.1, but we refuse to process chunk - # sizes that don't fit into 20 characters of hex - t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [Data(data=b"xxx")]) - - # refuses garbage in the chunk count - with pytest.raises(LocalProtocolError): - t_body_reader(ChunkedReader, b"10\x00\r\nxxx", None) - - # handles (and discards) "chunk extensions" omg wtf - t_body_reader( - ChunkedReader, - b"5; hello=there\r\n" - + b"xxxxx" - + b"\r\n" - + b'0; random="junk"; some=more; canbe=lonnnnngg\r\n\r\n', - [Data(data=b"xxxxx"), EndOfMessage()], - ) - - -def test_ContentLengthWriter(): - w = ContentLengthWriter(5) - assert dowrite(w, Data(data=b"123")) == b"123" - assert dowrite(w, Data(data=b"45")) == b"45" - assert dowrite(w, EndOfMessage()) == b"" - - w = ContentLengthWriter(5) - with pytest.raises(LocalProtocolError): - dowrite(w, Data(data=b"123456")) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) - with pytest.raises(LocalProtocolError): - dowrite(w, Data(data=b"456")) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage()) - - w = ContentLengthWriter(5) - dowrite(w, Data(data=b"123")) == b"123" - dowrite(w, Data(data=b"45")) == b"45" - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) - - -def test_ChunkedWriter(): - w = ChunkedWriter() - assert dowrite(w, Data(data=b"aaa")) == b"3\r\naaa\r\n" - assert dowrite(w, Data(data=b"a" * 20)) == b"14\r\n" + b"a" * 20 + b"\r\n" - - assert dowrite(w, Data(data=b"")) == b"" - - assert dowrite(w, EndOfMessage()) == b"0\r\n\r\n" - - assert ( - dowrite(w, EndOfMessage(headers=[("Etag", "asdf"), ("a", "b")])) - == b"0\r\nEtag: asdf\r\na: b\r\n\r\n" - ) - - -def test_Http10Writer(): - w = Http10Writer() - assert dowrite(w, Data(data=b"1234")) == b"1234" - assert dowrite(w, EndOfMessage()) == b"" - - with pytest.raises(LocalProtocolError): - dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) - - -def test_reject_garbage_after_request_line(): - with pytest.raises(LocalProtocolError): - tr(READERS[SERVER, SEND_RESPONSE], b"HTTP/1.0 200 OK\x00xxxx\r\n\r\n", None) - - -def test_reject_garbage_after_response_line(): - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1 xxxxxx\r\n" b"Host: a\r\n\r\n", - None, - ) - - -def test_reject_garbage_in_header_line(): - with pytest.raises(LocalProtocolError): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" b"Host: foo\x00bar\r\n\r\n", - None, - ) - - -def test_reject_non_vchar_in_path(): - for bad_char in b"\x00\x20\x7f\xee": - message = bytearray(b"HEAD /") - message.append(bad_char) - message.extend(b" HTTP/1.1\r\nHost: foobar\r\n\r\n") - with pytest.raises(LocalProtocolError): - tr(READERS[CLIENT, IDLE], message, None) - - -# https://github.com/python-hyper/h11/issues/57 -def test_allow_some_garbage_in_cookies(): - tr( - READERS[CLIENT, IDLE], - b"HEAD /foo HTTP/1.1\r\n" - b"Host: foo\r\n" - b"Set-Cookie: ___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900\r\n" - b"\r\n", - Request( - method="HEAD", - target="/foo", - headers=[ - ("Host", "foo"), - ("Set-Cookie", "___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900"), - ], - ), - ) - - -def test_host_comes_first(): - tw( - write_headers, - normalize_and_validate([("foo", "bar"), ("Host", "example.com")]), - b"Host: example.com\r\nfoo: bar\r\n\r\n", - ) diff --git a/env/lib/python3.8/site-packages/h11/tests/test_receivebuffer.py b/env/lib/python3.8/site-packages/h11/tests/test_receivebuffer.py deleted file mode 100644 index 2be220ba..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_receivebuffer.py +++ /dev/null @@ -1,78 +0,0 @@ -from .._receivebuffer import ReceiveBuffer - - -def test_receivebuffer(): - b = ReceiveBuffer() - assert not b - assert len(b) == 0 - assert bytes(b) == b"" - - b += b"123" - assert b - assert len(b) == 3 - assert bytes(b) == b"123" - - b.compress() - assert bytes(b) == b"123" - - assert b.maybe_extract_at_most(2) == b"12" - assert b - assert len(b) == 1 - assert bytes(b) == b"3" - - b.compress() - assert bytes(b) == b"3" - - assert b.maybe_extract_at_most(10) == b"3" - assert bytes(b) == b"" - - assert b.maybe_extract_at_most(10) is None - assert not b - - ################################################################ - # maybe_extract_until_next - ################################################################ - - b += b"12345a6789aa" - - assert b.maybe_extract_until_next(b"a") == b"12345a" - assert bytes(b) == b"6789aa" - - assert b.maybe_extract_until_next(b"aaa") is None - assert bytes(b) == b"6789aa" - - b += b"a12" - assert b.maybe_extract_until_next(b"aaa") == b"6789aaa" - assert bytes(b) == b"12" - - # check repeated searches for the same needle, triggering the - # pickup-where-we-left-off logic - b += b"345" - assert b.maybe_extract_until_next(b"aaa") is None - - b += b"6789aaa123" - assert b.maybe_extract_until_next(b"aaa") == b"123456789aaa" - assert bytes(b) == b"123" - - ################################################################ - # maybe_extract_lines - ################################################################ - - b += b"\r\na: b\r\nfoo:bar\r\n\r\ntrailing" - lines = b.maybe_extract_lines() - assert lines == [b"123", b"a: b", b"foo:bar"] - assert bytes(b) == b"trailing" - - assert b.maybe_extract_lines() is None - - b += b"\r\n\r" - assert b.maybe_extract_lines() is None - - assert b.maybe_extract_at_most(100) == b"trailing\r\n\r" - assert not b - - # Empty body case (as happens at the end of chunked encoding if there are - # no trailing headers, e.g.) - b += b"\r\ntrailing" - assert b.maybe_extract_lines() == [] - assert bytes(b) == b"trailing" diff --git a/env/lib/python3.8/site-packages/h11/tests/test_state.py b/env/lib/python3.8/site-packages/h11/tests/test_state.py deleted file mode 100644 index efe83f0a..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_state.py +++ /dev/null @@ -1,250 +0,0 @@ -import pytest - -from .._events import * -from .._state import * -from .._state import _SWITCH_CONNECT, _SWITCH_UPGRADE, ConnectionState -from .._util import LocalProtocolError - - -def test_ConnectionState(): - cs = ConnectionState() - - # Basic event-triggered transitions - - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - cs.process_event(CLIENT, Request) - # The SERVER-Request special case: - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - # Illegal transitions raise an error and nothing happens - with pytest.raises(LocalProtocolError): - cs.process_event(CLIENT, Request) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} - - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, EndOfMessage) - assert cs.states == {CLIENT: DONE, SERVER: DONE} - - # State-triggered transition - - cs.process_event(SERVER, ConnectionClosed) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} - - -def test_ConnectionState_keep_alive(): - # keep_alive = False - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} - - -def test_ConnectionState_keep_alive_in_DONE(): - # Check that if keep_alive is disabled when the CLIENT is already in DONE, - # then this is sufficient to immediately trigger the DONE -> MUST_CLOSE - # transition - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - assert cs.states[CLIENT] is DONE - cs.process_keep_alive_disabled() - assert cs.states[CLIENT] is MUST_CLOSE - - -def test_ConnectionState_switch_denied(): - for switch_type in (_SWITCH_CONNECT, _SWITCH_UPGRADE): - for deny_early in (True, False): - cs = ConnectionState() - cs.process_client_switch_proposal(switch_type) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - assert switch_type in cs.pending_switch_proposals - - if deny_early: - # before client reaches DONE - cs.process_event(SERVER, Response) - assert not cs.pending_switch_proposals - - cs.process_event(CLIENT, EndOfMessage) - - if deny_early: - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - else: - assert cs.states == { - CLIENT: MIGHT_SWITCH_PROTOCOL, - SERVER: SEND_RESPONSE, - } - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == { - CLIENT: MIGHT_SWITCH_PROTOCOL, - SERVER: SEND_RESPONSE, - } - - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - assert not cs.pending_switch_proposals - - -_response_type_for_switch = { - _SWITCH_UPGRADE: InformationalResponse, - _SWITCH_CONNECT: Response, - None: Response, -} - - -def test_ConnectionState_protocol_switch_accepted(): - for switch_event in [_SWITCH_UPGRADE, _SWITCH_CONNECT]: - cs = ConnectionState() - cs.process_client_switch_proposal(switch_event) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, InformationalResponse) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - cs.process_event(SERVER, _response_type_for_switch[switch_event], switch_event) - assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - - -def test_ConnectionState_double_protocol_switch(): - # CONNECT + Upgrade is legal! Very silly, but legal. So we support - # it. Because sometimes doing the silly thing is easier than not. - for server_switch in [None, _SWITCH_UPGRADE, _SWITCH_CONNECT]: - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_client_switch_proposal(_SWITCH_CONNECT) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - cs.process_event( - SERVER, _response_type_for_switch[server_switch], server_switch - ) - if server_switch is None: - assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} - else: - assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} - - -def test_ConnectionState_inconsistent_protocol_switch(): - for client_switches, server_switch in [ - ([], _SWITCH_CONNECT), - ([], _SWITCH_UPGRADE), - ([_SWITCH_UPGRADE], _SWITCH_CONNECT), - ([_SWITCH_CONNECT], _SWITCH_UPGRADE), - ]: - cs = ConnectionState() - for client_switch in client_switches: - cs.process_client_switch_proposal(client_switch) - cs.process_event(CLIENT, Request) - with pytest.raises(LocalProtocolError): - cs.process_event(SERVER, Response, server_switch) - - -def test_ConnectionState_keepalive_protocol_switch_interaction(): - # keep_alive=False + pending_switch_proposals - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, Data) - assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} - - # the protocol switch "wins" - cs.process_event(CLIENT, EndOfMessage) - assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} - - # but when the server denies the request, keep_alive comes back into play - cs.process_event(SERVER, Response) - assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_BODY} - - -def test_ConnectionState_reuse(): - cs = ConnectionState() - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - cs.start_next_cycle() - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - # No keepalive - - cs.process_event(CLIENT, Request) - cs.process_keep_alive_disabled() - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # One side closed - - cs = ConnectionState() - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(CLIENT, ConnectionClosed) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # Succesful protocol switch - - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, InformationalResponse, _SWITCH_UPGRADE) - - with pytest.raises(LocalProtocolError): - cs.start_next_cycle() - - # Failed protocol switch - - cs = ConnectionState() - cs.process_client_switch_proposal(_SWITCH_UPGRADE) - cs.process_event(CLIENT, Request) - cs.process_event(CLIENT, EndOfMessage) - cs.process_event(SERVER, Response) - cs.process_event(SERVER, EndOfMessage) - - cs.start_next_cycle() - assert cs.states == {CLIENT: IDLE, SERVER: IDLE} - - -def test_server_request_is_illegal(): - # There used to be a bug in how we handled the Request special case that - # made this allowed... - cs = ConnectionState() - with pytest.raises(LocalProtocolError): - cs.process_event(SERVER, Request) diff --git a/env/lib/python3.8/site-packages/h11/tests/test_util.py b/env/lib/python3.8/site-packages/h11/tests/test_util.py deleted file mode 100644 index 74ab33bd..00000000 --- a/env/lib/python3.8/site-packages/h11/tests/test_util.py +++ /dev/null @@ -1,99 +0,0 @@ -import re -import sys -import traceback - -import pytest - -from .._util import * - - -def test_ProtocolError(): - with pytest.raises(TypeError): - ProtocolError("abstract base class") - - -def test_LocalProtocolError(): - try: - raise LocalProtocolError("foo") - except LocalProtocolError as e: - assert str(e) == "foo" - assert e.error_status_hint == 400 - - try: - raise LocalProtocolError("foo", error_status_hint=418) - except LocalProtocolError as e: - assert str(e) == "foo" - assert e.error_status_hint == 418 - - def thunk(): - raise LocalProtocolError("a", error_status_hint=420) - - try: - try: - thunk() - except LocalProtocolError as exc1: - orig_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) - exc1._reraise_as_remote_protocol_error() - except RemoteProtocolError as exc2: - assert type(exc2) is RemoteProtocolError - assert exc2.args == ("a",) - assert exc2.error_status_hint == 420 - new_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) - assert new_traceback.endswith(orig_traceback) - - -def test_validate(): - my_re = re.compile(br"(?P[0-9]+)\.(?P[0-9]+)") - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.") - - groups = validate(my_re, b"0.1") - assert groups == {"group1": b"0", "group2": b"1"} - - # successful partial matches are an error - must match whole string - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.1xx") - with pytest.raises(LocalProtocolError): - validate(my_re, b"0.1\n") - - -def test_validate_formatting(): - my_re = re.compile(br"foo") - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops") - assert "oops" in str(excinfo.value) - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops {}") - assert "oops {}" in str(excinfo.value) - - with pytest.raises(LocalProtocolError) as excinfo: - validate(my_re, b"", "oops {} xx", 10) - assert "oops 10 xx" in str(excinfo.value) - - -def test_make_sentinel(): - S = make_sentinel("S") - assert repr(S) == "S" - assert S == S - assert type(S).__name__ == "S" - assert S in {S} - assert type(S) is S - S2 = make_sentinel("S2") - assert repr(S2) == "S2" - assert S != S2 - assert S not in {S2} - assert type(S) is not type(S2) - - -def test_bytesify(): - assert bytesify(b"123") == b"123" - assert bytesify(bytearray(b"123")) == b"123" - assert bytesify("123") == b"123" - - with pytest.raises(UnicodeEncodeError): - bytesify(u"\u1234") - - with pytest.raises(TypeError): - bytesify(10) diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/INSTALLER b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/LICENSE b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/LICENSE deleted file mode 100644 index b5083a50..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Timothy Edmund Crosley - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/METADATA b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/METADATA deleted file mode 100644 index 21ed02e8..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/METADATA +++ /dev/null @@ -1,712 +0,0 @@ -Metadata-Version: 2.1 -Name: isort -Version: 5.6.4 -Summary: A Python utility / library to sort Python imports. -Home-page: https://pycqa.github.io/isort/ -License: MIT -Keywords: Refactor,Lint,Imports,Sort,Clean -Author: Timothy Crosley -Author-email: timothy.crosley@gmail.com -Requires-Python: >=3.6,<4.0 -Classifier: Development Status :: 6 - Mature -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Natural Language :: English -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Software Development :: Libraries -Classifier: Topic :: Utilities -Provides-Extra: colors -Provides-Extra: pipfile_deprecated_finder -Provides-Extra: requirements_deprecated_finder -Requires-Dist: colorama (>=0.4.3,<0.5.0); extra == "colors" -Requires-Dist: pip-api; extra == "requirements_deprecated_finder" -Requires-Dist: pipreqs; extra == "pipfile_deprecated_finder" or extra == "requirements_deprecated_finder" -Requires-Dist: requirementslib; extra == "pipfile_deprecated_finder" -Project-URL: Changelog, https://github.com/pycqa/isort/blob/master/CHANGELOG.md -Project-URL: Documentation, https://pycqa.github.io/isort/ -Project-URL: Repository, https://github.com/pycqa/isort -Description-Content-Type: text/markdown - -[![isort - isort your imports, so you don't have to.](https://raw.githubusercontent.com/pycqa/isort/develop/art/logo_large.png)](https://pycqa.github.io/isort/) - ------------------------------------------------------------------------- - -[![PyPI version](https://badge.fury.io/py/isort.svg)](https://badge.fury.io/py/isort) -[![Test Status](https://github.com/pycqa/isort/workflows/Test/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ATest) -[![Lint Status](https://github.com/pycqa/isort/workflows/Lint/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ALint) -[![Code coverage Status](https://codecov.io/gh/pycqa/isort/branch/develop/graph/badge.svg)](https://codecov.io/gh/pycqa/isort) -[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.org/project/isort/) -[![Join the chat at https://gitter.im/timothycrosley/isort](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Downloads](https://pepy.tech/badge/isort)](https://pepy.tech/project/isort) -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) -[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) -[![DeepSource](https://static.deepsource.io/deepsource-badge-light-mini.svg)](https://deepsource.io/gh/pycqa/isort/?ref=repository-badge) -_________________ - -[Read Latest Documentation](https://pycqa.github.io/isort/) - [Browse GitHub Code Repository](https://github.com/pycqa/isort/) -_________________ - -isort your imports, so you don't have to. - -isort is a Python utility / library to sort imports alphabetically, and -automatically separated into sections and by type. It provides a command line -utility, Python library and [plugins for various -editors](https://github.com/pycqa/isort/wiki/isort-Plugins) to -quickly sort all your imports. It requires Python 3.6+ to run but -supports formatting Python 2 code too. - -[Try isort now from your browser!](https://pycqa.github.io/isort/docs/quick_start/0.-try/) - -![Example Usage](https://raw.github.com/pycqa/isort/develop/example.gif) - -Before isort: - -```python -from my_lib import Object - -import os - -from my_lib import Object3 - -from my_lib import Object2 - -import sys - -from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14 - -import sys - -from __future__ import absolute_import - -from third_party import lib3 - -print("Hey") -print("yo") -``` - -After isort: - -```python -from __future__ import absolute_import - -import os -import sys - -from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, - lib9, lib10, lib11, lib12, lib13, lib14, lib15) - -from my_lib import Object, Object2, Object3 - -print("Hey") -print("yo") -``` - -## Installing isort - -Installing isort is as simple as: - -```bash -pip install isort -``` - -Install isort with requirements.txt support: - -```bash -pip install isort[requirements_deprecated_finder] -``` - -Install isort with Pipfile support: - -```bash -pip install isort[pipfile_deprecated_finder] -``` - -Install isort with both formats support: - -```bash -pip install isort[requirements_deprecated_finder,pipfile_deprecated_finder] -``` - -## Using isort - -**From the command line**: - -```bash -isort mypythonfile.py mypythonfile2.py -``` - -or recursively: - -```bash -isort . -``` - -*which is equivalent to:* - -```bash -isort **/*.py -``` - -or to see the proposed changes without applying them: - -```bash -isort mypythonfile.py --diff -``` - -Finally, to atomically run isort against a project, only applying -changes if they don't introduce syntax errors do: - -```bash -isort --atomic . -``` - -(Note: this is disabled by default as it keeps isort from being able to -run against code written using a different version of Python) - -**From within Python**: - -```python -import isort - -isort.file("pythonfile.py") -``` - -or: - -```python -import isort - -sorted_code = isort.code("import b\nimport a\n") -``` - -## Installing isort's for your preferred text editor - -Several plugins have been written that enable to use isort from within a -variety of text-editors. You can find a full list of them [on the isort -wiki](https://github.com/pycqa/isort/wiki/isort-Plugins). -Additionally, I will enthusiastically accept pull requests that include -plugins for other text editors and add documentation for them as I am -notified. - -## Multi line output modes - -You will notice above the \"multi\_line\_output\" setting. This setting -defines how from imports wrap when they extend past the line\_length -limit and has 12 possible settings: - -**0 - Grid** - -```python -from third_party import (lib1, lib2, lib3, - lib4, lib5, ...) -``` - -**1 - Vertical** - -```python -from third_party import (lib1, - lib2, - lib3 - lib4, - lib5, - ...) -``` - -**2 - Hanging Indent** - -```python -from third_party import \ - lib1, lib2, lib3, \ - lib4, lib5, lib6 -``` - -**3 - Vertical Hanging Indent** - -```python -from third_party import ( - lib1, - lib2, - lib3, - lib4, -) -``` - -**4 - Hanging Grid** - -```python -from third_party import ( - lib1, lib2, lib3, lib4, - lib5, ...) -``` - -**5 - Hanging Grid Grouped** - -```python -from third_party import ( - lib1, lib2, lib3, lib4, - lib5, ... -) -``` - -**6 - Hanging Grid Grouped, No Trailing Comma** - -In Mode 5 isort leaves a single extra space to maintain consistency of -output when a comma is added at the end. Mode 6 is the same - except -that no extra space is maintained leading to the possibility of lines -one character longer. You can enforce a trailing comma by using this in -conjunction with `-tc` or `include_trailing_comma: True`. - -```python -from third_party import ( - lib1, lib2, lib3, lib4, - lib5 -) -``` - -**7 - NOQA** - -```python -from third_party import lib1, lib2, lib3, ... # NOQA -``` - -Alternatively, you can set `force_single_line` to `True` (`-sl` on the -command line) and every import will appear on its own line: - -```python -from third_party import lib1 -from third_party import lib2 -from third_party import lib3 -... -``` - -**8 - Vertical Hanging Indent Bracket** - -Same as Mode 3 - _Vertical Hanging Indent_ but the closing parentheses -on the last line is indented. - -```python -from third_party import ( - lib1, - lib2, - lib3, - lib4, - ) -``` - -**9 - Vertical Prefix From Module Import** - -Starts a new line with the same `from MODULE import ` prefix when lines are longer than the line length limit. - -```python -from third_party import lib1, lib2, lib3 -from third_party import lib4, lib5, lib6 -``` - -**10 - Hanging Indent With Parentheses** - -Same as Mode 2 - _Hanging Indent_ but uses parentheses instead of backslash -for wrapping long lines. - -```python -from third_party import ( - lib1, lib2, lib3, - lib4, lib5, lib6) -``` - -**11 - Backslash Grid** - -Same as Mode 0 - _Grid_ but uses backslashes instead of parentheses to group imports. - -```python -from third_party import lib1, lib2, lib3, \ - lib4, lib5 -``` - -## Indentation - -To change the how constant indents appear - simply change the -indent property with the following accepted formats: - -- Number of spaces you would like. For example: 4 would cause standard - 4 space indentation. -- Tab -- A verbatim string with quotes around it. - -For example: - -```python -" " -``` - -is equivalent to 4. - -For the import styles that use parentheses, you can control whether or -not to include a trailing comma after the last import with the -`include_trailing_comma` option (defaults to `False`). - -## Intelligently Balanced Multi-line Imports - -As of isort 3.1.0 support for balanced multi-line imports has been -added. With this enabled isort will dynamically change the import length -to the one that produces the most balanced grid, while staying below the -maximum import length defined. - -Example: - -```python -from __future__ import (absolute_import, division, - print_function, unicode_literals) -``` - -Will be produced instead of: - -```python -from __future__ import (absolute_import, division, print_function, - unicode_literals) -``` - -To enable this set `balanced_wrapping` to `True` in your config or pass -the `-e` option into the command line utility. - -## Custom Sections and Ordering - -You can change the section order with `sections` option from the default -of: - -```ini -FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER -``` - -to your preference: - -```ini -sections=FUTURE,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER -``` - -You also can define your own sections and their order. - -Example: - -```ini -known_django=django -known_pandas=pandas,numpy -sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,PANDAS,FIRSTPARTY,LOCALFOLDER -``` - -would create two new sections with the specified known modules. - -The `no_lines_before` option will prevent the listed sections from being -split from the previous section by an empty line. - -Example: - -```ini -sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER -no_lines_before=LOCALFOLDER -``` - -would produce a section with both FIRSTPARTY and LOCALFOLDER modules -combined. - -**IMPORTANT NOTE**: It is very important to know when setting `known` sections that the naming -does not directly map for historical reasons. For custom settings, the only difference is -capitalization (`known_custom=custom` VS `sections=CUSTOM,...`) for all others reference the -following mapping: - - - `known_standard_library` : `STANDARD_LIBRARY` - - `extra_standard_library` : `STANDARD_LIBRARY` # Like known standard library but appends instead of replacing - - `known_future_library` : `FUTURE` - - `known_first_party`: `FIRSTPARTY` - - `known_third_party`: `THIRDPARTY` - - `known_local_folder`: `LOCALFOLDER` - -This will likely be changed in isort 6.0.0+ in a backwards compatible way. - -## Auto-comment import sections - -Some projects prefer to have import sections uniquely titled to aid in -identifying the sections quickly when visually scanning. isort can -automate this as well. To do this simply set the -`import_heading_{section_name}` setting for each section you wish to -have auto commented - to the desired comment. - -For Example: - -```ini -import_heading_stdlib=Standard Library -import_heading_firstparty=My Stuff -``` - -Would lead to output looking like the following: - -```python -# Standard Library -import os -import sys - -import django.settings - -# My Stuff -import myproject.test -``` - -## Ordering by import length - -isort also makes it easy to sort your imports by length, simply by -setting the `length_sort` option to `True`. This will result in the -following output style: - -```python -from evn.util import ( - Pool, - Dict, - Options, - Constant, - DecayDict, - UnexpectedCodePath, -) -``` - -It is also possible to opt-in to sorting imports by length for only -specific sections by using `length_sort_` followed by the section name -as a configuration item, e.g.: - - length_sort_stdlib=1 - -## Controlling how isort sections `from` imports - -By default isort places straight (`import y`) imports above from imports (`from x import y`): - -```python -import b -from a import a # This will always appear below because it is a from import. -``` - -However, if you prefer to keep strict alphabetical sorting you can set [force sort within sections](https://pycqa.github.io/isort/docs/configuration/options/#force-sort-within-sections) to true. Resulting in: - - -```python -from a import a # This will now appear at top because a appears in the alphabet before b -import b -``` - -You can even tell isort to always place from imports on top, instead of the default of placing them on bottom, using [from first](https://pycqa.github.io/isort/docs/configuration/options/#from-first). - -```python -from b import b # If from first is set to True, all from imports will be placed before non-from imports. -import a -``` - -## Skip processing of imports (outside of configuration) - -To make isort ignore a single import simply add a comment at the end of -the import line containing the text `isort:skip`: - -```python -import module # isort:skip -``` - -or: - -```python -from xyz import (abc, # isort:skip - yo, - hey) -``` - -To make isort skip an entire file simply add `isort:skip_file` to the -module's doc string: - -```python -""" my_module.py - Best module ever - - isort:skip_file -""" - -import b -import a -``` - -## Adding an import to multiple files - -isort makes it easy to add an import statement across multiple files, -while being assured it's correctly placed. - -To add an import to all files: - -```bash -isort -a "from __future__ import print_function" *.py -``` - -To add an import only to files that already have imports: - -```bash -isort -a "from __future__ import print_function" --append-only *.py -``` - - -## Removing an import from multiple files - -isort also makes it easy to remove an import from multiple files, -without having to be concerned with how it was originally formatted. - -From the command line: - -```bash -isort --rm "os.system" *.py -``` - -## Using isort to verify code - -The `--check-only` option -------------------------- - -isort can also be used to verify that code is correctly formatted -by running it with `-c`. Any files that contain incorrectly sorted -and/or formatted imports will be outputted to `stderr`. - -```bash -isort **/*.py -c -v - -SUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good! -ERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted. -``` - -One great place this can be used is with a pre-commit git hook, such as -this one by \@acdha: - - - -This can help to ensure a certain level of code quality throughout a -project. - -Git hook --------- - -isort provides a hook function that can be integrated into your Git -pre-commit script to check Python code before committing. - -To cause the commit to fail if there are isort errors (strict mode), -include the following in `.git/hooks/pre-commit`: - -```python -#!/usr/bin/env python -import sys -from isort.hooks import git_hook - -sys.exit(git_hook(strict=True, modify=True, lazy=True, settings_file="")) -``` - -If you just want to display warnings, but allow the commit to happen -anyway, call `git_hook` without the strict parameter. If you want to -display warnings, but not also fix the code, call `git_hook` without the -modify parameter. -The `lazy` argument is to support users who are "lazy" to add files -individually to the index and tend to use `git commit -a` instead. -Set it to `True` to ensure all tracked files are properly isorted, -leave it out or set it to `False` to check only files added to your -index. - -If you want to use a specific configuration file for the hook, you can pass its -path to settings_file. If no path is specifically requested, `git_hook` will -search for the configuration file starting at the directory containing the first -staged file, as per `git diff-index` ordering, and going upward in the directory -structure until a valid configuration file is found or -[`MAX_CONFIG_SEARCH_DEPTH`](src/config.py:35) directories are checked. -The settings_file parameter is used to support users who keep their configuration -file in a directory that might not be a parent of all the other files. - -## Setuptools integration - -Upon installation, isort enables a `setuptools` command that checks -Python files declared by your project. - -Running `python setup.py isort` on the command line will check the files -listed in your `py_modules` and `packages`. If any warning is found, the -command will exit with an error code: - -```bash -$ python setup.py isort -``` - -Also, to allow users to be able to use the command without having to -install isort themselves, add isort to the setup\_requires of your -`setup()` like so: - -```python -setup( - name="project", - packages=["project"], - - setup_requires=[ - "isort" - ] -) -``` - -## Spread the word - -[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) - -Place this badge at the top of your repository to let others know your project uses isort. - -For README.md: - -```markdown -[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) -``` - -Or README.rst: - -```rst -.. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336 - :target: https://pycqa.github.io/isort/ -``` - -## Security contact information - -To report a security vulnerability, please use the [Tidelift security -contact](https://tidelift.com/security). Tidelift will coordinate the -fix and disclosure. - -## Why isort? - -isort simply stands for import sort. It was originally called -"sortImports" however I got tired of typing the extra characters and -came to the realization camelCase is not pythonic. - -I wrote isort because in an organization I used to work in the manager -came in one day and decided all code must have alphabetically sorted -imports. The code base was huge - and he meant for us to do it by hand. -However, being a programmer - I\'m too lazy to spend 8 hours mindlessly -performing a function, but not too lazy to spend 16 hours automating it. -I was given permission to open source sortImports and here we are :) - ------------------------------------------------------------------------- - -[Get professionally supported isort with the Tidelift -Subscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme) - -Professional support for isort is available as part of the [Tidelift -Subscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme). -Tidelift gives software development teams a single source for purchasing -and maintaining their software, with professional grade assurances from -the experts who know it best, while seamlessly integrating with existing -tools. - ------------------------------------------------------------------------- - -Thanks and I hope you find isort useful! - -~Timothy Crosley - diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/RECORD b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/RECORD deleted file mode 100644 index 580be51f..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/RECORD +++ /dev/null @@ -1,96 +0,0 @@ -../../../bin/isort,sha256=zX8NBdfUpd1ZYtYd3ba9m0GQsPO66C8o2V_6I9zPBa8,254 -isort-5.6.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -isort-5.6.4.dist-info/LICENSE,sha256=BjKUABw9Uj26y6ud1UrCKZgnVsyvWSylMkCysM3YIGU,1089 -isort-5.6.4.dist-info/METADATA,sha256=bY4FamQg0TqGLkZbxP5sjdJx-e5P11hpyC-iFWVVuUM,19947 -isort-5.6.4.dist-info/RECORD,, -isort-5.6.4.dist-info/WHEEL,sha256=xSvaL1DM8LOHfdyo0cCcwjZu1tC6CnCsRGWUgazvlbM,83 -isort-5.6.4.dist-info/entry_points.txt,sha256=7dJFJ8ssCeyoMpdKE7RDH-A5qBWWqgcJh_-RSqMIB0U,142 -isort/__init__.py,sha256=u8zdFTPFro_l9J7JzdeNSlu6CU6BboY3fRTuloxbl7c,374 -isort/__main__.py,sha256=iK0trzN9CCXpQX-XPZDZ9JVkm2Lc0q0oiAgsa6FkJb4,36 -isort/__pycache__/__init__.cpython-38.pyc,, -isort/__pycache__/__main__.cpython-38.pyc,, -isort/__pycache__/_version.cpython-38.pyc,, -isort/__pycache__/api.cpython-38.pyc,, -isort/__pycache__/comments.cpython-38.pyc,, -isort/__pycache__/core.cpython-38.pyc,, -isort/__pycache__/exceptions.cpython-38.pyc,, -isort/__pycache__/format.cpython-38.pyc,, -isort/__pycache__/hooks.cpython-38.pyc,, -isort/__pycache__/io.cpython-38.pyc,, -isort/__pycache__/literal.cpython-38.pyc,, -isort/__pycache__/logo.cpython-38.pyc,, -isort/__pycache__/main.cpython-38.pyc,, -isort/__pycache__/output.cpython-38.pyc,, -isort/__pycache__/parse.cpython-38.pyc,, -isort/__pycache__/place.cpython-38.pyc,, -isort/__pycache__/profiles.cpython-38.pyc,, -isort/__pycache__/pylama_isort.cpython-38.pyc,, -isort/__pycache__/sections.cpython-38.pyc,, -isort/__pycache__/settings.cpython-38.pyc,, -isort/__pycache__/setuptools_commands.cpython-38.pyc,, -isort/__pycache__/sorting.cpython-38.pyc,, -isort/__pycache__/utils.cpython-38.pyc,, -isort/__pycache__/wrap.cpython-38.pyc,, -isort/__pycache__/wrap_modes.cpython-38.pyc,, -isort/_future/__init__.py,sha256=wn-Aa4CVe0zZfA_YBTkJqb6LA9HR9NgpAp0uatzNRNs,326 -isort/_future/__pycache__/__init__.cpython-38.pyc,, -isort/_future/__pycache__/_dataclasses.cpython-38.pyc,, -isort/_future/_dataclasses.py,sha256=zrstLAFOKIHRWJjXdZuHJG2EPiyTVFSQuBcsPpXCCnk,44112 -isort/_vendored/toml/LICENSE,sha256=LZKUgj32yJNXyL5JJ_znk2HWVh5e51MtWSbmOTmqpTY,1252 -isort/_vendored/toml/__init__.py,sha256=gKOk-Amczi2juJsOs1D6UEToaPSIIgNh95Yo5N5gneE,703 -isort/_vendored/toml/__pycache__/__init__.cpython-38.pyc,, -isort/_vendored/toml/__pycache__/decoder.cpython-38.pyc,, -isort/_vendored/toml/__pycache__/encoder.cpython-38.pyc,, -isort/_vendored/toml/__pycache__/ordered.cpython-38.pyc,, -isort/_vendored/toml/__pycache__/tz.cpython-38.pyc,, -isort/_vendored/toml/decoder.py,sha256=5etBKNvVLFAR0rhLCJ9fnRTlqkebI4ZQeoJi_myFbd4,37713 -isort/_vendored/toml/encoder.py,sha256=gQOXYnAWo27Jc_przA1FqLX5AgwbdgN-qDHQtKRx300,9668 -isort/_vendored/toml/ordered.py,sha256=aW5woa5xOqR4BjIz9t10_lghxyhF54KQ7FqUNVv7WJ0,334 -isort/_vendored/toml/tz.py,sha256=8TAiXrTqU08sE0ruz2TXH_pFY2rlwNKE47MSE4rDo8Y,618 -isort/_version.py,sha256=0ryPPy_pGvnG-2tow_ZyL1kF53oMzA7cQOo9s_W0fRQ,22 -isort/api.py,sha256=bSuFdTNkiaSx4OYGdDO_w2A4PctagCAI1V85txrhI90,16022 -isort/comments.py,sha256=23uMZZbUn8y3glMW6_WftnEhECvc-4LW4ysEghpYUUU,962 -isort/core.py,sha256=yetJPY4U8VPGghsFPqG0Wi2Zwnd6pyhW8V2wFTp_Uuw,17848 -isort/deprecated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -isort/deprecated/__pycache__/__init__.cpython-38.pyc,, -isort/deprecated/__pycache__/finders.cpython-38.pyc,, -isort/deprecated/finders.py,sha256=UOb9z4qPmfzCVlME_OtASEOO8_DcE-mEU-oidkFPnRU,14768 -isort/exceptions.py,sha256=C7xcnrkM64TmxhOUMbc6qtMsXYdTYjZPhFp_upOlNbQ,5877 -isort/format.py,sha256=z_Mf1T2IXh9TyNYY9dw-nWSAfsqWxLvzLwTov7nojuM,5111 -isort/hooks.py,sha256=VatU5IHqBFfTAtl4gaIqr7WocV7r-_6ndtDcrnwq_Y8,3146 -isort/io.py,sha256=sMBvc2VaJ9LijzAq7tVGmlRBRx3goxya_K1E5ayoR74,2057 -isort/literal.py,sha256=4jKIU49AQnH89NZd9Av6CL86glpQB0qxAiVK6pgsYNo,3467 -isort/logo.py,sha256=cL3al79O7O0G2viqRMRfBPp0qtRZmJw2nHSCZw8XWdQ,388 -isort/main.py,sha256=atAWyAZaH5NwztIrmATGCpnKc7H1E0RElV3VL8_RPRQ,35851 -isort/output.py,sha256=XyjtAOnYcFIobMZHdllJY-3X-IxfxPps0aD-ezku22M,23979 -isort/parse.py,sha256=-Oi2K9eJJYuRXPGmAGeUnL3TiOvlf3xj9eWUSOPur34,23147 -isort/place.py,sha256=8gzh3xbhlhQzCiZVv-Z-Bi2XXMYQUJCOLjlJIgXnT90,5165 -isort/profiles.py,sha256=B5iORUoSyiltJ8gDLNodmDaYWir9Nblm1R-CvkYKuWk,1601 -isort/pylama_isort.py,sha256=Ci1K6BPgrxSZC0KO2P4dnz-vQgjWDbnpZe_Rt-0ml1I,1165 -isort/sections.py,sha256=xG5bwU4tOIKUmeBBhZ45EIfjP8HgDOx796bPvD5zWCw,297 -isort/settings.py,sha256=I6iwKTe0EGdETfbzyTrzQy8kGj7u610SCFrfcGIQTp4,28393 -isort/setuptools_commands.py,sha256=zj0C96fXMz-iQv9oPViGPU0xidbx5oYMf5VO1vDKHR0,2263 -isort/sorting.py,sha256=gdcSfo2MFWPGfEPOgVN5dJuLFkBbbZR4nQybNjIQByM,3233 -isort/stdlibs/__init__.py,sha256=MgiO4yPeJZ6ieWz5qSw2LuY7pVmRjZUaCqyUaLH5qJQ,64 -isort/stdlibs/__pycache__/__init__.cpython-38.pyc,, -isort/stdlibs/__pycache__/all.cpython-38.pyc,, -isort/stdlibs/__pycache__/py2.cpython-38.pyc,, -isort/stdlibs/__pycache__/py27.cpython-38.pyc,, -isort/stdlibs/__pycache__/py3.cpython-38.pyc,, -isort/stdlibs/__pycache__/py35.cpython-38.pyc,, -isort/stdlibs/__pycache__/py36.cpython-38.pyc,, -isort/stdlibs/__pycache__/py37.cpython-38.pyc,, -isort/stdlibs/__pycache__/py38.cpython-38.pyc,, -isort/stdlibs/__pycache__/py39.cpython-38.pyc,, -isort/stdlibs/all.py,sha256=n8Es1WK6UlupYyVvf1PDjGbionqix-afC3LkY8nzTcw,57 -isort/stdlibs/py2.py,sha256=dTgWTa7ggz1cwN8fuI9eIs9-5nTmkRxG_uO61CGwfXI,41 -isort/stdlibs/py27.py,sha256=-Id4l2pjAOMXUfwDNnIBR2o8I_mW_Ghmuek2b82Bczk,4492 -isort/stdlibs/py3.py,sha256=899xi1UHQAHxkYJU4lx44qbj41Md85V9Bi05uz5zAts,121 -isort/stdlibs/py35.py,sha256=SVZp9jaCVq4kSjbKcVgF8dJttyFCqcl20ydodsmHrqE,3283 -isort/stdlibs/py36.py,sha256=tCGWDZXWlJJI4_845yOhTpIvnU0-a3TouD_xsMEIZ3s,3298 -isort/stdlibs/py37.py,sha256=nYZmN-s3qMmAHHddegQv6U0j4cnAH0e5SmqTiG6mmhQ,3322 -isort/stdlibs/py38.py,sha256=KE_65iAHg7icOv2xSGScdJWjwBZGuSQYfYcTSIoo_d8,3307 -isort/stdlibs/py39.py,sha256=gHmC2xbsvrqqxybV9G7vrKRv7UmZpgt9NybAhR1LANk,3295 -isort/utils.py,sha256=ohk1VB5WvwXzU8TW3qTWBqQcH1QEA-qUH41Zkw_EVnU,665 -isort/wrap.py,sha256=GiQNWBSOtDEVO2o5OSUpSvEc_7D_SOVdpdLuBVhJDNc,5828 -isort/wrap_modes.py,sha256=BCBV4l89JjVqbfL8cI_i29eSPniUoAb__jKEHqZhFGQ,11258 diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/WHEEL b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/WHEEL deleted file mode 100644 index bbb34895..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: poetry 1.0.5 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/entry_points.txt deleted file mode 100644 index b221602f..00000000 --- a/env/lib/python3.8/site-packages/isort-5.6.4.dist-info/entry_points.txt +++ /dev/null @@ -1,9 +0,0 @@ -[console_scripts] -isort=isort.main:main - -[distutils.commands] -isort=isort.main:ISortCommand - -[pylama.linter] -isort=isort.pylama_isort:Linter - diff --git a/env/lib/python3.8/site-packages/isort/__init__.py b/env/lib/python3.8/site-packages/isort/__init__.py deleted file mode 100644 index 236255dd..00000000 --- a/env/lib/python3.8/site-packages/isort/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Defines the public isort interface""" -from . import settings -from ._version import __version__ -from .api import check_code_string as check_code -from .api import check_file, check_stream, place_module, place_module_with_reason -from .api import sort_code_string as code -from .api import sort_file as file -from .api import sort_stream as stream -from .settings import Config diff --git a/env/lib/python3.8/site-packages/isort/__main__.py b/env/lib/python3.8/site-packages/isort/__main__.py deleted file mode 100644 index 94b1d057..00000000 --- a/env/lib/python3.8/site-packages/isort/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from isort.main import main - -main() diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 332bf5434c0f8e9184e5b1a6bf3c3ca9013e56e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 640 zcmY+Bzi!(w5XLE4mi5oAlXl2xbn}pK=#rrb3bb>Vq6-&RkzHLGJh$9TimkypsC*z3pz@`jy7F2_`!vvcI? zE7{dQ-+hL?P++%ifbDd=9YwblRvWh!%7NLp9sI@G$u9AQ1?Pl1Smc`X6BsMB;vDT+ zH$ZpCJKY1f&fuY4=Bqil7bEy)X552T`eqt2FPFMM;@-t`$A1Vna6DzT!o-_U%8R^- zFJmmE4TVHA=S7=;(rPabUv_W&it}D~oO@zIqkZvIu~`JWXeVJZB=%TmDBdhFVDccV zAVrW8#byxSaf$NpI~}wHYN0dWv;uk%4*zP>mL8R$Q`=#` zWvebN7;Gd3b)uuVrPI9|w0eJaO|5WniRbRx16UfLgmNwv=HXYc*S K(!_c3xc&!QQ?*L~ diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/__main__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/__main__.cpython-38.pyc deleted file mode 100644 index b19c6c3602fca88f08be210b613b07a9395a2b76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmWIL<>g`kf^F@G;#Gk3V-N=!FabFZKwK;aBvKes7;_kM8KW2(8B!UW85kK-n1UHJ znO_3s7&IAgvE(LZ=J{zdMR8>o=NFaefw)B=6IL=5F#{%>?HAmOP#3VP_$kg`k0*mQ~;>CdUV-N=!FakLaKwQiLBvKfn7*ZI688n%ySWWfJ^i2FT8E#mBE?C}IMt0~5az^fU5vQ}v5elZ#SI^7B&l(=$uri&6{ni}g$MGW81* zlS?vEa})D)i&Kk$Cg`W;mFeeXCg~ScmSp7T8S7c-7iX5F>H^heC#I(s>t`0{7nSJ4 ZEYmBfyv1RYo1apelWGTYi8?b)K1>ot+)*E&vh)K#8IT0wi&15{R8BrE;kp*)*ZhQAk;!OnKvYHQb&B z2H2fh_so(6YT!ed%8eEesrX>JiimxokE$F~Ipmm1xqM2c=IV=m^C3=bB$4vH*RwwW zK~Yi?RVm?aO;1n%yzYM8{eHggx2jb~!|&zq|9$hXzNBeCr;qX91U_EH6TfO`n$U#a z(HiQlH*|a(9iv-l6m&`}bj)tCQRKMUvAU&3scSdvZn;tJIt_=@i=ByXrBUIy)v0!C zjT+)5VRt6GM#JEExii(BZcKNNHI8+UH;#8_8Z(^kbWU_<8?)WH#$0#4G0$leX#Zs6 zB*!bAr@Bu!PI0`7_%n^u9Ithr?Ya%OyUVDWRi}WsIyyqZq3_8lxKXqId?iPm54~ zOIll(>w0FdB{B%tFI_?0e8WpN>SktN=_NrFdY#O=>fcH(UCD}Xg-FQEmKP^f@TMn2 zdbc9!|567jd>BE5x-%DV1#tq3YujPs-MT1cB;#yyHR$+jTS4za)b09VGD=wU6Dpm} zUJ4T#iGIr$<2CDrY{`qanm0H6WW$%uBx-uSUT3@6+VH}4Kc<8>XlHXR>3fOaOnli5 z(Dh~y!@@^49dAT8oBc3o2fk>Epxs7aix<1SWE&Byi#9txV#idhc{4~hnxGX&Vcp1T zU%j~c<+onH+PrY(^6I76GV4MVwuAN6x-)y{ z^j#w{(o$-tdTJoYOpC&}Q_{86zF!c9J)L9bo`$J5yqZ@(ng-auHV_p#FTqTM(B0NYemxSZ7+{?mL_u0f|@!vy1wbR5+cx#eHV)^RcRrjVByS;v=gR!?|)E!YfxKM~>>~lxnxhnhqJ8sZ+x1&Dl zhnyO$huC_U8Cq6c6myvmqK%PaZewP`sD9gHycvMmVdT=j z7&h06y1hQHufejQ1x9n$+=BR7k7*cR#)8gAjqQsqu9zRIQ9m#;leVFJ3R|jPlqd1x zxO|#orzm)a0+wJ!iG8AFrKTd7P0+Gzsv%`&?E71piQ$QQSiR3O4=I*_=_~6&0wL6k;uT1)m7dq49p{DTV_)9z<%%EP zSm^}US9;sYMil<;^2;l6kof0OZp(vITnVV}D_$>H?rmpNJP=xi)CsI*>V8b4*Jf`` or ```` - if completion_type: - paths = auto_complete_paths(current, completion_type) - options = [(path, 0) for path in paths] - for option in options: - opt_label = option[0] - # append '=' to options which require args - if option[1] and option[0][:2] == "--": - opt_label += '=' - print(opt_label) - else: - # show main parser options only when necessary - - opts = [i.option_list for i in parser.option_groups] - opts.append(parser.option_list) - flattened_opts = chain.from_iterable(opts) - if current.startswith('-'): - for opt in flattened_opts: - if opt.help != optparse.SUPPRESS_HELP: - subcommands += opt._long_opts + opt._short_opts - else: - # get completion type given cwords and all available options - completion_type = get_path_completion_type(cwords, cword, - flattened_opts) - if completion_type: - subcommands = list(auto_complete_paths(current, - completion_type)) - - print(' '.join([x for x in subcommands if x.startswith(current)])) - sys.exit(1) - - -def get_path_completion_type(cwords, cword, opts): - # type: (List[str], int, Iterable[Any]) -> Optional[str] - """Get the type of path completion (``file``, ``dir``, ``path`` or None) - - :param cwords: same as the environmental variable ``COMP_WORDS`` - :param cword: same as the environmental variable ``COMP_CWORD`` - :param opts: The available options to check - :return: path completion type (``file``, ``dir``, ``path`` or None) - """ - if cword < 2 or not cwords[cword - 2].startswith('-'): - return None - for opt in opts: - if opt.help == optparse.SUPPRESS_HELP: - continue - for o in str(opt).split('/'): - if cwords[cword - 2].split('=')[0] == o: - if not opt.metavar or any( - x in ('path', 'file', 'dir') - for x in opt.metavar.split('/')): - return opt.metavar - return None - - -def auto_complete_paths(current, completion_type): - # type: (str, str) -> Iterable[str] - """If ``completion_type`` is ``file`` or ``path``, list all regular files - and directories starting with ``current``; otherwise only list directories - starting with ``current``. - - :param current: The word to be completed - :param completion_type: path completion type(`file`, `path` or `dir`)i - :return: A generator of regular files and/or directories - """ - directory, filename = os.path.split(current) - current_path = os.path.abspath(directory) - # Don't complete paths if they can't be accessed - if not os.access(current_path, os.R_OK): - return - filename = os.path.normcase(filename) - # list all files that start with ``filename`` - file_list = (x for x in os.listdir(current_path) - if os.path.normcase(x).startswith(filename)) - for f in file_list: - opt = os.path.join(current_path, f) - comp_file = os.path.normcase(os.path.join(directory, f)) - # complete regular files when there is not ```` after option - # complete directories when there is ````, ```` or - # ````after option - if completion_type != 'dir' and os.path.isfile(opt): - yield comp_file - elif os.path.isdir(opt): - yield os.path.join(comp_file, '') diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/base_command.py b/env/lib/python3.8/site-packages/pip/_internal/cli/base_command.py deleted file mode 100644 index 1fa5ba0b..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/base_command.py +++ /dev/null @@ -1,228 +0,0 @@ -"""Base Command class, and related routines""" - -from __future__ import absolute_import, print_function - -import logging -import logging.config -import optparse -import os -import platform -import sys -import traceback - -from pip._internal.cli import cmdoptions -from pip._internal.cli.command_context import CommandContextMixIn -from pip._internal.cli.parser import ( - ConfigOptionParser, - UpdatingDefaultsHelpFormatter, -) -from pip._internal.cli.status_codes import ( - ERROR, - PREVIOUS_BUILD_DIR_ERROR, - SUCCESS, - UNKNOWN_ERROR, - VIRTUALENV_NOT_FOUND, -) -from pip._internal.exceptions import ( - BadCommand, - CommandError, - InstallationError, - PreviousBuildDirError, - UninstallationError, -) -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging -from pip._internal.utils.misc import get_prog, normalize_path -from pip._internal.utils.temp_dir import ( - global_tempdir_manager, - tempdir_registry, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.virtualenv import running_under_virtualenv - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Tuple, Any - from optparse import Values - - from pip._internal.utils.temp_dir import ( - TempDirectoryTypeRegistry as TempDirRegistry - ) - -__all__ = ['Command'] - -logger = logging.getLogger(__name__) - - -class Command(CommandContextMixIn): - usage = None # type: str - ignore_require_venv = False # type: bool - - def __init__(self, name, summary, isolated=False): - # type: (str, str, bool) -> None - super(Command, self).__init__() - parser_kw = { - 'usage': self.usage, - 'prog': '{} {}'.format(get_prog(), name), - 'formatter': UpdatingDefaultsHelpFormatter(), - 'add_help_option': False, - 'name': name, - 'description': self.__doc__, - 'isolated': isolated, - } - - self.name = name - self.summary = summary - self.parser = ConfigOptionParser(**parser_kw) - - self.tempdir_registry = None # type: Optional[TempDirRegistry] - - # Commands should add options to this option group - optgroup_name = '{} Options'.format(self.name.capitalize()) - self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) - - # Add the general options - gen_opts = cmdoptions.make_option_group( - cmdoptions.general_group, - self.parser, - ) - self.parser.add_option_group(gen_opts) - - def handle_pip_version_check(self, options): - # type: (Values) -> None - """ - This is a no-op so that commands by default do not do the pip version - check. - """ - # Make sure we do the pip version check if the index_group options - # are present. - assert not hasattr(options, 'no_index') - - def run(self, options, args): - # type: (Values, List[Any]) -> Any - raise NotImplementedError - - def parse_args(self, args): - # type: (List[str]) -> Tuple[Any, Any] - # factored out for testability - return self.parser.parse_args(args) - - def main(self, args): - # type: (List[str]) -> int - try: - with self.main_context(): - return self._main(args) - finally: - logging.shutdown() - - def _main(self, args): - # type: (List[str]) -> int - # We must initialize this before the tempdir manager, otherwise the - # configuration would not be accessible by the time we clean up the - # tempdir manager. - self.tempdir_registry = self.enter_context(tempdir_registry()) - # Intentionally set as early as possible so globally-managed temporary - # directories are available to the rest of the code. - self.enter_context(global_tempdir_manager()) - - options, args = self.parse_args(args) - - # Set verbosity so that it can be used elsewhere. - self.verbosity = options.verbose - options.quiet - - level_number = setup_logging( - verbosity=self.verbosity, - no_color=options.no_color, - user_log_file=options.log, - ) - - if ( - sys.version_info[:2] == (2, 7) and - not options.no_python_version_warning - ): - message = ( - "pip 21.0 will drop support for Python 2.7 in January 2021. " - "More details about Python 2 support in pip, can be found at " - "https://pip.pypa.io/en/latest/development/release-process/#python-2-support" # noqa - ) - if platform.python_implementation() == "CPython": - message = ( - "Python 2.7 reached the end of its life on January " - "1st, 2020. Please upgrade your Python as Python 2.7 " - "is no longer maintained. " - ) + message - deprecated(message, replacement=None, gone_in=None) - - # TODO: Try to get these passing down from the command? - # without resorting to os.environ to hold these. - # This also affects isolated builds and it should. - - if options.no_input: - os.environ['PIP_NO_INPUT'] = '1' - - if options.exists_action: - os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) - - if options.require_venv and not self.ignore_require_venv: - # If a venv is required check if it can really be found - if not running_under_virtualenv(): - logger.critical( - 'Could not find an activated virtualenv (required).' - ) - sys.exit(VIRTUALENV_NOT_FOUND) - - if options.cache_dir: - options.cache_dir = normalize_path(options.cache_dir) - if not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "or is not writable by the current user. The cache " - "has been disabled. Check the permissions and owner of " - "that directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None - - try: - status = self.run(options, args) - # FIXME: all commands should return an exit status - # and when it is done, isinstance is not needed anymore - if isinstance(status, int): - return status - except PreviousBuildDirError as exc: - logger.critical(str(exc)) - logger.debug('Exception information:', exc_info=True) - - return PREVIOUS_BUILD_DIR_ERROR - except (InstallationError, UninstallationError, BadCommand) as exc: - logger.critical(str(exc)) - logger.debug('Exception information:', exc_info=True) - - return ERROR - except CommandError as exc: - logger.critical('%s', exc) - logger.debug('Exception information:', exc_info=True) - - return ERROR - except BrokenStdoutLoggingError: - # Bypass our logger and write any remaining messages to stderr - # because stdout no longer works. - print('ERROR: Pipe to stdout was broken', file=sys.stderr) - if level_number <= logging.DEBUG: - traceback.print_exc(file=sys.stderr) - - return ERROR - except KeyboardInterrupt: - logger.critical('Operation cancelled by user') - logger.debug('Exception information:', exc_info=True) - - return ERROR - except BaseException: - logger.critical('Exception:', exc_info=True) - - return UNKNOWN_ERROR - finally: - self.handle_pip_version_check(options) - - return SUCCESS diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py b/env/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py deleted file mode 100644 index c2347841..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py +++ /dev/null @@ -1,962 +0,0 @@ -""" -shared options and groups - -The principle here is to define options once, but *not* instantiate them -globally. One reason being that options with action='append' can carry state -between parses. pip parses general options twice internally, and shouldn't -pass on state. To be consistent, all options will follow this design. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging -import os -import textwrap -import warnings -from distutils.util import strtobool -from functools import partial -from optparse import SUPPRESS_HELP, Option, OptionGroup -from textwrap import dedent - -from pip._internal.cli.progress_bars import BAR_TYPES -from pip._internal.exceptions import CommandError -from pip._internal.locations import USER_CACHE_DIR, get_src_prefix -from pip._internal.models.format_control import FormatControl -from pip._internal.models.index import PyPI -from pip._internal.models.target_python import TargetPython -from pip._internal.utils.hashes import STRONG_HASHES -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Callable, Dict, Optional, Tuple - from optparse import OptionParser, Values - from pip._internal.cli.parser import ConfigOptionParser - -logger = logging.getLogger(__name__) - - -def raise_option_error(parser, option, msg): - # type: (OptionParser, Option, str) -> None - """ - Raise an option parsing error using parser.error(). - - Args: - parser: an OptionParser instance. - option: an Option instance. - msg: the error text. - """ - msg = '{} error: {}'.format(option, msg) - msg = textwrap.fill(' '.join(msg.split())) - parser.error(msg) - - -def make_option_group(group, parser): - # type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup - """ - Return an OptionGroup object - group -- assumed to be dict with 'name' and 'options' keys - parser -- an optparse Parser - """ - option_group = OptionGroup(parser, group['name']) - for option in group['options']: - option_group.add_option(option()) - return option_group - - -def check_install_build_global(options, check_options=None): - # type: (Values, Optional[Values]) -> None - """Disable wheels if per-setup.py call options are set. - - :param options: The OptionParser options to update. - :param check_options: The options to check, if not supplied defaults to - options. - """ - if check_options is None: - check_options = options - - def getname(n): - # type: (str) -> Optional[Any] - return getattr(check_options, n, None) - names = ["build_options", "global_options", "install_options"] - if any(map(getname, names)): - control = options.format_control - control.disallow_binaries() - warnings.warn( - 'Disabling all use of wheels due to the use of --build-option ' - '/ --global-option / --install-option.', stacklevel=2, - ) - - -def check_dist_restriction(options, check_target=False): - # type: (Values, bool) -> None - """Function for determining if custom platform options are allowed. - - :param options: The OptionParser options. - :param check_target: Whether or not to check if --target is being used. - """ - dist_restriction_set = any([ - options.python_version, - options.platform, - options.abi, - options.implementation, - ]) - - binary_only = FormatControl(set(), {':all:'}) - sdist_dependencies_allowed = ( - options.format_control != binary_only and - not options.ignore_dependencies - ) - - # Installations or downloads using dist restrictions must not combine - # source distributions and dist-specific wheels, as they are not - # guaranteed to be locally compatible. - if dist_restriction_set and sdist_dependencies_allowed: - raise CommandError( - "When restricting platform and interpreter constraints using " - "--python-version, --platform, --abi, or --implementation, " - "either --no-deps must be set, or --only-binary=:all: must be " - "set and --no-binary must not be set (or must be set to " - ":none:)." - ) - - if check_target: - if dist_restriction_set and not options.target_dir: - raise CommandError( - "Can not use any platform or abi specific options unless " - "installing via '--target'" - ) - - -def _path_option_check(option, opt, value): - # type: (Option, str, str) -> str - return os.path.expanduser(value) - - -class PipOption(Option): - TYPES = Option.TYPES + ("path",) - TYPE_CHECKER = Option.TYPE_CHECKER.copy() - TYPE_CHECKER["path"] = _path_option_check - - -########### -# options # -########### - -help_ = partial( - Option, - '-h', '--help', - dest='help', - action='help', - help='Show help.', -) # type: Callable[..., Option] - -isolated_mode = partial( - Option, - "--isolated", - dest="isolated_mode", - action="store_true", - default=False, - help=( - "Run pip in an isolated mode, ignoring environment variables and user " - "configuration." - ), -) # type: Callable[..., Option] - -require_virtualenv = partial( - Option, - # Run only if inside a virtualenv, bail if not. - '--require-virtualenv', '--require-venv', - dest='require_venv', - action='store_true', - default=False, - help=SUPPRESS_HELP -) # type: Callable[..., Option] - -verbose = partial( - Option, - '-v', '--verbose', - dest='verbose', - action='count', - default=0, - help='Give more output. Option is additive, and can be used up to 3 times.' -) # type: Callable[..., Option] - -no_color = partial( - Option, - '--no-color', - dest='no_color', - action='store_true', - default=False, - help="Suppress colored output", -) # type: Callable[..., Option] - -version = partial( - Option, - '-V', '--version', - dest='version', - action='store_true', - help='Show version and exit.', -) # type: Callable[..., Option] - -quiet = partial( - Option, - '-q', '--quiet', - dest='quiet', - action='count', - default=0, - help=( - 'Give less output. Option is additive, and can be used up to 3' - ' times (corresponding to WARNING, ERROR, and CRITICAL logging' - ' levels).' - ), -) # type: Callable[..., Option] - -progress_bar = partial( - Option, - '--progress-bar', - dest='progress_bar', - type='choice', - choices=list(BAR_TYPES.keys()), - default='on', - help=( - 'Specify type of progress to be displayed [' + - '|'.join(BAR_TYPES.keys()) + '] (default: %default)' - ), -) # type: Callable[..., Option] - -log = partial( - PipOption, - "--log", "--log-file", "--local-log", - dest="log", - metavar="path", - type="path", - help="Path to a verbose appending log." -) # type: Callable[..., Option] - -no_input = partial( - Option, - # Don't ask for input - '--no-input', - dest='no_input', - action='store_true', - default=False, - help=SUPPRESS_HELP -) # type: Callable[..., Option] - -proxy = partial( - Option, - '--proxy', - dest='proxy', - type='str', - default='', - help="Specify a proxy in the form [user:passwd@]proxy.server:port." -) # type: Callable[..., Option] - -retries = partial( - Option, - '--retries', - dest='retries', - type='int', - default=5, - help="Maximum number of retries each connection should attempt " - "(default %default times).", -) # type: Callable[..., Option] - -timeout = partial( - Option, - '--timeout', '--default-timeout', - metavar='sec', - dest='timeout', - type='float', - default=15, - help='Set the socket timeout (default %default seconds).', -) # type: Callable[..., Option] - - -def exists_action(): - # type: () -> Option - return Option( - # Option when path already exist - '--exists-action', - dest='exists_action', - type='choice', - choices=['s', 'i', 'w', 'b', 'a'], - default=[], - action='append', - metavar='action', - help="Default action when a path already exists: " - "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.", - ) - - -cert = partial( - PipOption, - '--cert', - dest='cert', - type='path', - metavar='path', - help="Path to alternate CA bundle.", -) # type: Callable[..., Option] - -client_cert = partial( - PipOption, - '--client-cert', - dest='client_cert', - type='path', - default=None, - metavar='path', - help="Path to SSL client certificate, a single file containing the " - "private key and the certificate in PEM format.", -) # type: Callable[..., Option] - -index_url = partial( - Option, - '-i', '--index-url', '--pypi-url', - dest='index_url', - metavar='URL', - default=PyPI.simple_url, - help="Base URL of the Python Package Index (default %default). " - "This should point to a repository compliant with PEP 503 " - "(the simple repository API) or a local directory laid out " - "in the same format.", -) # type: Callable[..., Option] - - -def extra_index_url(): - # type: () -> Option - return Option( - '--extra-index-url', - dest='extra_index_urls', - metavar='URL', - action='append', - default=[], - help="Extra URLs of package indexes to use in addition to " - "--index-url. Should follow the same rules as " - "--index-url.", - ) - - -no_index = partial( - Option, - '--no-index', - dest='no_index', - action='store_true', - default=False, - help='Ignore package index (only looking at --find-links URLs instead).', -) # type: Callable[..., Option] - - -def find_links(): - # type: () -> Option - return Option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='url', - help="If a URL or path to an html file, then parse for links to " - "archives such as sdist (.tar.gz) or wheel (.whl) files. " - "If a local path or file:// URL that's a directory, " - "then look for archives in the directory listing. " - "Links to VCS project URLs are not supported.", - ) - - -def trusted_host(): - # type: () -> Option - return Option( - "--trusted-host", - dest="trusted_hosts", - action="append", - metavar="HOSTNAME", - default=[], - help="Mark this host or host:port pair as trusted, even though it " - "does not have valid or any HTTPS.", - ) - - -def constraints(): - # type: () -> Option - return Option( - '-c', '--constraint', - dest='constraints', - action='append', - default=[], - metavar='file', - help='Constrain versions using the given constraints file. ' - 'This option can be used multiple times.' - ) - - -def requirements(): - # type: () -> Option - return Option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help='Install from the given requirements file. ' - 'This option can be used multiple times.' - ) - - -def editable(): - # type: () -> Option - return Option( - '-e', '--editable', - dest='editables', - action='append', - default=[], - metavar='path/url', - help=('Install a project in editable mode (i.e. setuptools ' - '"develop mode") from a local project path or a VCS url.'), - ) - - -def _handle_src(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - value = os.path.abspath(value) - setattr(parser.values, option.dest, value) - - -src = partial( - PipOption, - '--src', '--source', '--source-dir', '--source-directory', - dest='src_dir', - type='path', - metavar='dir', - default=get_src_prefix(), - action='callback', - callback=_handle_src, - help='Directory to check out editable projects into. ' - 'The default in a virtualenv is "/src". ' - 'The default for global installs is "/src".' -) # type: Callable[..., Option] - - -def _get_format_control(values, option): - # type: (Values, Option) -> Any - """Get a format_control object.""" - return getattr(values, option.dest) - - -def _handle_no_binary(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - existing = _get_format_control(parser.values, option) - FormatControl.handle_mutual_excludes( - value, existing.no_binary, existing.only_binary, - ) - - -def _handle_only_binary(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - existing = _get_format_control(parser.values, option) - FormatControl.handle_mutual_excludes( - value, existing.only_binary, existing.no_binary, - ) - - -def no_binary(): - # type: () -> Option - format_control = FormatControl(set(), set()) - return Option( - "--no-binary", dest="format_control", action="callback", - callback=_handle_no_binary, type="str", - default=format_control, - help='Do not use binary packages. Can be supplied multiple times, and ' - 'each time adds to the existing value. Accepts either ":all:" to ' - 'disable all binary packages, ":none:" to empty the set (notice ' - 'the colons), or one or more package names with commas between ' - 'them (no colons). Note that some packages are tricky to compile ' - 'and may fail to install when this option is used on them.', - ) - - -def only_binary(): - # type: () -> Option - format_control = FormatControl(set(), set()) - return Option( - "--only-binary", dest="format_control", action="callback", - callback=_handle_only_binary, type="str", - default=format_control, - help='Do not use source packages. Can be supplied multiple times, and ' - 'each time adds to the existing value. Accepts either ":all:" to ' - 'disable all source packages, ":none:" to empty the set, or one ' - 'or more package names with commas between them. Packages ' - 'without binary distributions will fail to install when this ' - 'option is used on them.', - ) - - -platform = partial( - Option, - '--platform', - dest='platform', - metavar='platform', - default=None, - help=("Only use wheels compatible with . " - "Defaults to the platform of the running system."), -) # type: Callable[..., Option] - - -# This was made a separate function for unit-testing purposes. -def _convert_python_version(value): - # type: (str) -> Tuple[Tuple[int, ...], Optional[str]] - """ - Convert a version string like "3", "37", or "3.7.3" into a tuple of ints. - - :return: A 2-tuple (version_info, error_msg), where `error_msg` is - non-None if and only if there was a parsing error. - """ - if not value: - # The empty string is the same as not providing a value. - return (None, None) - - parts = value.split('.') - if len(parts) > 3: - return ((), 'at most three version parts are allowed') - - if len(parts) == 1: - # Then we are in the case of "3" or "37". - value = parts[0] - if len(value) > 1: - parts = [value[0], value[1:]] - - try: - version_info = tuple(int(part) for part in parts) - except ValueError: - return ((), 'each version part must be an integer') - - return (version_info, None) - - -def _handle_python_version(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - """ - Handle a provided --python-version value. - """ - version_info, error_msg = _convert_python_version(value) - if error_msg is not None: - msg = ( - 'invalid --python-version value: {!r}: {}'.format( - value, error_msg, - ) - ) - raise_option_error(parser, option=option, msg=msg) - - parser.values.python_version = version_info - - -python_version = partial( - Option, - '--python-version', - dest='python_version', - metavar='python_version', - action='callback', - callback=_handle_python_version, type='str', - default=None, - help=dedent("""\ - The Python interpreter version to use for wheel and "Requires-Python" - compatibility checks. Defaults to a version derived from the running - interpreter. The version can be specified using up to three dot-separated - integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor - version can also be given as a string without dots (e.g. "37" for 3.7.0). - """), -) # type: Callable[..., Option] - - -implementation = partial( - Option, - '--implementation', - dest='implementation', - metavar='implementation', - default=None, - help=("Only use wheels compatible with Python " - "implementation , e.g. 'pp', 'jy', 'cp', " - " or 'ip'. If not specified, then the current " - "interpreter implementation is used. Use 'py' to force " - "implementation-agnostic wheels."), -) # type: Callable[..., Option] - - -abi = partial( - Option, - '--abi', - dest='abi', - metavar='abi', - default=None, - help=("Only use wheels compatible with Python " - "abi , e.g. 'pypy_41'. If not specified, then the " - "current interpreter abi tag is used. Generally " - "you will need to specify --implementation, " - "--platform, and --python-version when using " - "this option."), -) # type: Callable[..., Option] - - -def add_target_python_options(cmd_opts): - # type: (OptionGroup) -> None - cmd_opts.add_option(platform()) - cmd_opts.add_option(python_version()) - cmd_opts.add_option(implementation()) - cmd_opts.add_option(abi()) - - -def make_target_python(options): - # type: (Values) -> TargetPython - target_python = TargetPython( - platform=options.platform, - py_version_info=options.python_version, - abi=options.abi, - implementation=options.implementation, - ) - - return target_python - - -def prefer_binary(): - # type: () -> Option - return Option( - "--prefer-binary", - dest="prefer_binary", - action="store_true", - default=False, - help="Prefer older binary packages over newer source packages." - ) - - -cache_dir = partial( - PipOption, - "--cache-dir", - dest="cache_dir", - default=USER_CACHE_DIR, - metavar="dir", - type='path', - help="Store the cache data in ." -) # type: Callable[..., Option] - - -def _handle_no_cache_dir(option, opt, value, parser): - # type: (Option, str, str, OptionParser) -> None - """ - Process a value provided for the --no-cache-dir option. - - This is an optparse.Option callback for the --no-cache-dir option. - """ - # The value argument will be None if --no-cache-dir is passed via the - # command-line, since the option doesn't accept arguments. However, - # the value can be non-None if the option is triggered e.g. by an - # environment variable, like PIP_NO_CACHE_DIR=true. - if value is not None: - # Then parse the string value to get argument error-checking. - try: - strtobool(value) - except ValueError as exc: - raise_option_error(parser, option=option, msg=str(exc)) - - # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool() - # converted to 0 (like "false" or "no") caused cache_dir to be disabled - # rather than enabled (logic would say the latter). Thus, we disable - # the cache directory not just on values that parse to True, but (for - # backwards compatibility reasons) also on values that parse to False. - # In other words, always set it to False if the option is provided in - # some (valid) form. - parser.values.cache_dir = False - - -no_cache = partial( - Option, - "--no-cache-dir", - dest="cache_dir", - action="callback", - callback=_handle_no_cache_dir, - help="Disable the cache.", -) # type: Callable[..., Option] - -no_deps = partial( - Option, - '--no-deps', '--no-dependencies', - dest='ignore_dependencies', - action='store_true', - default=False, - help="Don't install package dependencies.", -) # type: Callable[..., Option] - - -def _handle_build_dir(option, opt, value, parser): - # type: (Option, str, str, OptionParser) -> None - if value: - value = os.path.abspath(value) - setattr(parser.values, option.dest, value) - - -build_dir = partial( - PipOption, - '-b', '--build', '--build-dir', '--build-directory', - dest='build_dir', - type='path', - metavar='dir', - action='callback', - callback=_handle_build_dir, - help='Directory to unpack packages into and build in. Note that ' - 'an initial build still takes place in a temporary directory. ' - 'The location of temporary directories can be controlled by setting ' - 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' - 'When passed, build directories are not cleaned in case of failures.' -) # type: Callable[..., Option] - -ignore_requires_python = partial( - Option, - '--ignore-requires-python', - dest='ignore_requires_python', - action='store_true', - help='Ignore the Requires-Python information.' -) # type: Callable[..., Option] - -no_build_isolation = partial( - Option, - '--no-build-isolation', - dest='build_isolation', - action='store_false', - default=True, - help='Disable isolation when building a modern source distribution. ' - 'Build dependencies specified by PEP 518 must be already installed ' - 'if this option is used.' -) # type: Callable[..., Option] - - -def _handle_no_use_pep517(option, opt, value, parser): - # type: (Option, str, str, OptionParser) -> None - """ - Process a value provided for the --no-use-pep517 option. - - This is an optparse.Option callback for the no_use_pep517 option. - """ - # Since --no-use-pep517 doesn't accept arguments, the value argument - # will be None if --no-use-pep517 is passed via the command-line. - # However, the value can be non-None if the option is triggered e.g. - # by an environment variable, for example "PIP_NO_USE_PEP517=true". - if value is not None: - msg = """A value was passed for --no-use-pep517, - probably using either the PIP_NO_USE_PEP517 environment variable - or the "no-use-pep517" config file option. Use an appropriate value - of the PIP_USE_PEP517 environment variable or the "use-pep517" - config file option instead. - """ - raise_option_error(parser, option=option, msg=msg) - - # Otherwise, --no-use-pep517 was passed via the command-line. - parser.values.use_pep517 = False - - -use_pep517 = partial( - Option, - '--use-pep517', - dest='use_pep517', - action='store_true', - default=None, - help='Use PEP 517 for building source distributions ' - '(use --no-use-pep517 to force legacy behaviour).' -) # type: Any - -no_use_pep517 = partial( - Option, - '--no-use-pep517', - dest='use_pep517', - action='callback', - callback=_handle_no_use_pep517, - default=None, - help=SUPPRESS_HELP -) # type: Any - -install_options = partial( - Option, - '--install-option', - dest='install_options', - action='append', - metavar='options', - help="Extra arguments to be supplied to the setup.py install " - "command (use like --install-option=\"--install-scripts=/usr/local/" - "bin\"). Use multiple --install-option options to pass multiple " - "options to setup.py install. If you are using an option with a " - "directory path, be sure to use absolute path.", -) # type: Callable[..., Option] - -global_options = partial( - Option, - '--global-option', - dest='global_options', - action='append', - metavar='options', - help="Extra global options to be supplied to the setup.py " - "call before the install command.", -) # type: Callable[..., Option] - -no_clean = partial( - Option, - '--no-clean', - action='store_true', - default=False, - help="Don't clean up build directories." -) # type: Callable[..., Option] - -pre = partial( - Option, - '--pre', - action='store_true', - default=False, - help="Include pre-release and development versions. By default, " - "pip only finds stable versions.", -) # type: Callable[..., Option] - -disable_pip_version_check = partial( - Option, - "--disable-pip-version-check", - dest="disable_pip_version_check", - action="store_true", - default=True, - help="Don't periodically check PyPI to determine whether a new version " - "of pip is available for download. Implied with --no-index.", -) # type: Callable[..., Option] - - -# Deprecated, Remove later -always_unzip = partial( - Option, - '-Z', '--always-unzip', - dest='always_unzip', - action='store_true', - help=SUPPRESS_HELP, -) # type: Callable[..., Option] - - -def _handle_merge_hash(option, opt_str, value, parser): - # type: (Option, str, str, OptionParser) -> None - """Given a value spelled "algo:digest", append the digest to a list - pointed to in a dict by the algo name.""" - if not parser.values.hashes: - parser.values.hashes = {} - try: - algo, digest = value.split(':', 1) - except ValueError: - parser.error('Arguments to {} must be a hash name ' - 'followed by a value, like --hash=sha256:' - 'abcde...'.format(opt_str)) - if algo not in STRONG_HASHES: - parser.error('Allowed hash algorithms for {} are {}.'.format( - opt_str, ', '.join(STRONG_HASHES))) - parser.values.hashes.setdefault(algo, []).append(digest) - - -hash = partial( - Option, - '--hash', - # Hash values eventually end up in InstallRequirement.hashes due to - # __dict__ copying in process_line(). - dest='hashes', - action='callback', - callback=_handle_merge_hash, - type='string', - help="Verify that the package's archive matches this " - 'hash before installing. Example: --hash=sha256:abcdef...', -) # type: Callable[..., Option] - - -require_hashes = partial( - Option, - '--require-hashes', - dest='require_hashes', - action='store_true', - default=False, - help='Require a hash to check each requirement against, for ' - 'repeatable installs. This option is implied when any package in a ' - 'requirements file has a --hash option.', -) # type: Callable[..., Option] - - -list_path = partial( - PipOption, - '--path', - dest='path', - type='path', - action='append', - help='Restrict to the specified installation path for listing ' - 'packages (can be used multiple times).' -) # type: Callable[..., Option] - - -def check_list_path_option(options): - # type: (Values) -> None - if options.path and (options.user or options.local): - raise CommandError( - "Cannot combine '--path' with '--user' or '--local'" - ) - - -no_python_version_warning = partial( - Option, - '--no-python-version-warning', - dest='no_python_version_warning', - action='store_true', - default=False, - help='Silence deprecation warnings for upcoming unsupported Pythons.', -) # type: Callable[..., Option] - - -unstable_feature = partial( - Option, - '--unstable-feature', - dest='unstable_features', - metavar='feature', - action='append', - default=[], - choices=['resolver'], - help=SUPPRESS_HELP, # TODO: Enable this when the resolver actually works. - # help='Enable unstable feature(s) that may be backward incompatible.', -) # type: Callable[..., Option] - - -########## -# groups # -########## - -general_group = { - 'name': 'General Options', - 'options': [ - help_, - isolated_mode, - require_virtualenv, - verbose, - version, - quiet, - log, - no_input, - proxy, - retries, - timeout, - exists_action, - trusted_host, - cert, - client_cert, - cache_dir, - no_cache, - disable_pip_version_check, - no_color, - no_python_version_warning, - unstable_feature, - ] -} # type: Dict[str, Any] - -index_group = { - 'name': 'Package Index Options', - 'options': [ - index_url, - extra_index_url, - no_index, - find_links, - ] -} # type: Dict[str, Any] diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/command_context.py b/env/lib/python3.8/site-packages/pip/_internal/cli/command_context.py deleted file mode 100644 index d1a64a77..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/command_context.py +++ /dev/null @@ -1,36 +0,0 @@ -from contextlib import contextmanager - -from pip._vendor.contextlib2 import ExitStack - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterator, ContextManager, TypeVar - - _T = TypeVar('_T', covariant=True) - - -class CommandContextMixIn(object): - def __init__(self): - # type: () -> None - super(CommandContextMixIn, self).__init__() - self._in_main_context = False - self._main_context = ExitStack() - - @contextmanager - def main_context(self): - # type: () -> Iterator[None] - assert not self._in_main_context - - self._in_main_context = True - try: - with self._main_context: - yield - finally: - self._in_main_context = False - - def enter_context(self, context_provider): - # type: (ContextManager[_T]) -> _T - assert self._in_main_context - - return self._main_context.enter_context(context_provider) diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/main.py b/env/lib/python3.8/site-packages/pip/_internal/cli/main.py deleted file mode 100644 index 172f30dd..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/main.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Primary application entrypoint. -""" -from __future__ import absolute_import - -import locale -import logging -import os -import sys - -from pip._internal.cli.autocompletion import autocomplete -from pip._internal.cli.main_parser import parse_command -from pip._internal.commands import create_command -from pip._internal.exceptions import PipError -from pip._internal.utils import deprecation -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional - -logger = logging.getLogger(__name__) - - -# Do not import and use main() directly! Using it directly is actively -# discouraged by pip's maintainers. The name, location and behavior of -# this function is subject to change, so calling it directly is not -# portable across different pip versions. - -# In addition, running pip in-process is unsupported and unsafe. This is -# elaborated in detail at -# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program. -# That document also provides suggestions that should work for nearly -# all users that are considering importing and using main() directly. - -# However, we know that certain users will still want to invoke pip -# in-process. If you understand and accept the implications of using pip -# in an unsupported manner, the best approach is to use runpy to avoid -# depending on the exact location of this entry point. - -# The following example shows how to use runpy to invoke pip in that -# case: -# -# sys.argv = ["pip", your, args, here] -# runpy.run_module("pip", run_name="__main__") -# -# Note that this will exit the process after running, unlike a direct -# call to main. As it is not safe to do any processing after calling -# main, this should not be an issue in practice. - -def main(args=None): - # type: (Optional[List[str]]) -> int - if args is None: - args = sys.argv[1:] - - # Configure our deprecation warnings to be sent through loggers - deprecation.install_warning_logger() - - autocomplete() - - try: - cmd_name, cmd_args = parse_command(args) - except PipError as exc: - sys.stderr.write("ERROR: {}".format(exc)) - sys.stderr.write(os.linesep) - sys.exit(1) - - # Needed for locale.getpreferredencoding(False) to work - # in pip._internal.utils.encoding.auto_decode - try: - locale.setlocale(locale.LC_ALL, '') - except locale.Error as e: - # setlocale can apparently crash if locale are uninitialized - logger.debug("Ignoring error %s when setting locale", e) - command = create_command(cmd_name, isolated=("--isolated" in cmd_args)) - - return command.main(cmd_args) diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py b/env/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py deleted file mode 100644 index 08c82c1f..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py +++ /dev/null @@ -1,99 +0,0 @@ -"""A single place for constructing and exposing the main parser -""" - -import os -import sys - -from pip._internal.cli import cmdoptions -from pip._internal.cli.parser import ( - ConfigOptionParser, - UpdatingDefaultsHelpFormatter, -) -from pip._internal.commands import commands_dict, get_similar_commands -from pip._internal.exceptions import CommandError -from pip._internal.utils.misc import get_pip_version, get_prog -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Tuple, List - - -__all__ = ["create_main_parser", "parse_command"] - - -def create_main_parser(): - # type: () -> ConfigOptionParser - """Creates and returns the main parser for pip's CLI - """ - - parser_kw = { - 'usage': '\n%prog [options]', - 'add_help_option': False, - 'formatter': UpdatingDefaultsHelpFormatter(), - 'name': 'global', - 'prog': get_prog(), - } - - parser = ConfigOptionParser(**parser_kw) - parser.disable_interspersed_args() - - parser.version = get_pip_version() - - # add the general options - gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) - parser.add_option_group(gen_opts) - - # so the help formatter knows - parser.main = True # type: ignore - - # create command listing for description - description = [''] + [ - '{name:27} {command_info.summary}'.format(**locals()) - for name, command_info in commands_dict.items() - ] - parser.description = '\n'.join(description) - - return parser - - -def parse_command(args): - # type: (List[str]) -> Tuple[str, List[str]] - parser = create_main_parser() - - # Note: parser calls disable_interspersed_args(), so the result of this - # call is to split the initial args into the general options before the - # subcommand and everything else. - # For example: - # args: ['--timeout=5', 'install', '--user', 'INITools'] - # general_options: ['--timeout==5'] - # args_else: ['install', '--user', 'INITools'] - general_options, args_else = parser.parse_args(args) - - # --version - if general_options.version: - sys.stdout.write(parser.version) # type: ignore - sys.stdout.write(os.linesep) - sys.exit() - - # pip || pip help -> print_help() - if not args_else or (args_else[0] == 'help' and len(args_else) == 1): - parser.print_help() - sys.exit() - - # the subcommand name - cmd_name = args_else[0] - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = ['unknown command "{}"'.format(cmd_name)] - if guess: - msg.append('maybe you meant "{}"'.format(guess)) - - raise CommandError(' - '.join(msg)) - - # all the args without the subcommand - cmd_args = args[:] - cmd_args.remove(cmd_name) - - return cmd_name, cmd_args diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/parser.py b/env/lib/python3.8/site-packages/pip/_internal/cli/parser.py deleted file mode 100644 index 04e00b72..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/parser.py +++ /dev/null @@ -1,266 +0,0 @@ -"""Base option parser setup""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import optparse -import sys -import textwrap -from distutils.util import strtobool - -from pip._vendor.six import string_types - -from pip._internal.cli.status_codes import UNKNOWN_ERROR -from pip._internal.configuration import Configuration, ConfigurationError -from pip._internal.utils.compat import get_terminal_size - -logger = logging.getLogger(__name__) - - -class PrettyHelpFormatter(optparse.IndentedHelpFormatter): - """A prettier/less verbose help formatter for optparse.""" - - def __init__(self, *args, **kwargs): - # help position must be aligned with __init__.parseopts.description - kwargs['max_help_position'] = 30 - kwargs['indent_increment'] = 1 - kwargs['width'] = get_terminal_size()[0] - 2 - optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) - - def format_option_strings(self, option): - return self._format_option_strings(option) - - def _format_option_strings(self, option, mvarfmt=' <{}>', optsep=', '): - """ - Return a comma-separated list of option strings and metavars. - - :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') - :param mvarfmt: metavar format string - :param optsep: separator - """ - opts = [] - - if option._short_opts: - opts.append(option._short_opts[0]) - if option._long_opts: - opts.append(option._long_opts[0]) - if len(opts) > 1: - opts.insert(1, optsep) - - if option.takes_value(): - metavar = option.metavar or option.dest.lower() - opts.append(mvarfmt.format(metavar.lower())) - - return ''.join(opts) - - def format_heading(self, heading): - if heading == 'Options': - return '' - return heading + ':\n' - - def format_usage(self, usage): - """ - Ensure there is only one newline between usage and the first heading - if there is no description. - """ - msg = '\nUsage: {}\n'.format( - self.indent_lines(textwrap.dedent(usage), " ")) - return msg - - def format_description(self, description): - # leave full control over description to us - if description: - if hasattr(self.parser, 'main'): - label = 'Commands' - else: - label = 'Description' - # some doc strings have initial newlines, some don't - description = description.lstrip('\n') - # some doc strings have final newlines and spaces, some don't - description = description.rstrip() - # dedent, then reindent - description = self.indent_lines(textwrap.dedent(description), " ") - description = '{}:\n{}\n'.format(label, description) - return description - else: - return '' - - def format_epilog(self, epilog): - # leave full control over epilog to us - if epilog: - return epilog - else: - return '' - - def indent_lines(self, text, indent): - new_lines = [indent + line for line in text.split('\n')] - return "\n".join(new_lines) - - -class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): - """Custom help formatter for use in ConfigOptionParser. - - This is updates the defaults before expanding them, allowing - them to show up correctly in the help listing. - """ - - def expand_default(self, option): - if self.parser is not None: - self.parser._update_defaults(self.parser.defaults) - return optparse.IndentedHelpFormatter.expand_default(self, option) - - -class CustomOptionParser(optparse.OptionParser): - - def insert_option_group(self, idx, *args, **kwargs): - """Insert an OptionGroup at a given position.""" - group = self.add_option_group(*args, **kwargs) - - self.option_groups.pop() - self.option_groups.insert(idx, group) - - return group - - @property - def option_list_all(self): - """Get a list of all options, including those in option groups.""" - res = self.option_list[:] - for i in self.option_groups: - res.extend(i.option_list) - - return res - - -class ConfigOptionParser(CustomOptionParser): - """Custom option parser which updates its defaults by checking the - configuration files and environmental variables""" - - def __init__(self, *args, **kwargs): - self.name = kwargs.pop('name') - - isolated = kwargs.pop("isolated", False) - self.config = Configuration(isolated) - - assert self.name - optparse.OptionParser.__init__(self, *args, **kwargs) - - def check_default(self, option, key, val): - try: - return option.check_value(key, val) - except optparse.OptionValueError as exc: - print("An error occurred during configuration: {}".format(exc)) - sys.exit(3) - - def _get_ordered_configuration_items(self): - # Configuration gives keys in an unordered manner. Order them. - override_order = ["global", self.name, ":env:"] - - # Pool the options into different groups - section_items = {name: [] for name in override_order} - for section_key, val in self.config.items(): - # ignore empty values - if not val: - logger.debug( - "Ignoring configuration key '%s' as it's value is empty.", - section_key - ) - continue - - section, key = section_key.split(".", 1) - if section in override_order: - section_items[section].append((key, val)) - - # Yield each group in their override order - for section in override_order: - for key, val in section_items[section]: - yield key, val - - def _update_defaults(self, defaults): - """Updates the given defaults with values from the config files and - the environ. Does a little special handling for certain types of - options (lists).""" - - # Accumulate complex default state. - self.values = optparse.Values(self.defaults) - late_eval = set() - # Then set the options with those values - for key, val in self._get_ordered_configuration_items(): - # '--' because configuration supports only long names - option = self.get_option('--' + key) - - # Ignore options not present in this parser. E.g. non-globals put - # in [global] by users that want them to apply to all applicable - # commands. - if option is None: - continue - - if option.action in ('store_true', 'store_false', 'count'): - try: - val = strtobool(val) - except ValueError: - error_msg = invalid_config_error_message( - option.action, key, val - ) - self.error(error_msg) - - elif option.action == 'append': - val = val.split() - val = [self.check_default(option, key, v) for v in val] - elif option.action == 'callback': - late_eval.add(option.dest) - opt_str = option.get_opt_string() - val = option.convert_value(opt_str, val) - # From take_action - args = option.callback_args or () - kwargs = option.callback_kwargs or {} - option.callback(option, opt_str, val, self, *args, **kwargs) - else: - val = self.check_default(option, key, val) - - defaults[option.dest] = val - - for key in late_eval: - defaults[key] = getattr(self.values, key) - self.values = None - return defaults - - def get_default_values(self): - """Overriding to make updating the defaults after instantiation of - the option parser possible, _update_defaults() does the dirty work.""" - if not self.process_default_values: - # Old, pre-Optik 1.5 behaviour. - return optparse.Values(self.defaults) - - # Load the configuration, or error out in case of an error - try: - self.config.load() - except ConfigurationError as err: - self.exit(UNKNOWN_ERROR, str(err)) - - defaults = self._update_defaults(self.defaults.copy()) # ours - for option in self._get_all_options(): - default = defaults.get(option.dest) - if isinstance(default, string_types): - opt_str = option.get_opt_string() - defaults[option.dest] = option.check_value(opt_str, default) - return optparse.Values(defaults) - - def error(self, msg): - self.print_usage(sys.stderr) - self.exit(UNKNOWN_ERROR, "{}\n".format(msg)) - - -def invalid_config_error_message(action, key, val): - """Returns a better error message when invalid configuration option - is provided.""" - if action in ('store_true', 'store_false'): - return ("{0} is not a valid value for {1} option, " - "please specify a boolean value like yes/no, " - "true/false or 1/0 instead.").format(val, key) - - return ("{0} is not a valid value for {1} option, " - "please specify a numerical value like 1/0 " - "instead.").format(val, key) diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/progress_bars.py b/env/lib/python3.8/site-packages/pip/_internal/cli/progress_bars.py deleted file mode 100644 index 7ed22479..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/progress_bars.py +++ /dev/null @@ -1,277 +0,0 @@ -from __future__ import division - -import itertools -import sys -from signal import SIGINT, default_int_handler, signal - -from pip._vendor import six -from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar -from pip._vendor.progress.spinner import Spinner - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.logging import get_indentation -from pip._internal.utils.misc import format_size -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Dict, List - -try: - from pip._vendor import colorama -# Lots of different errors can come from this, including SystemError and -# ImportError. -except Exception: - colorama = None - - -def _select_progress_class(preferred, fallback): - # type: (Bar, Bar) -> Bar - encoding = getattr(preferred.file, "encoding", None) - - # If we don't know what encoding this file is in, then we'll just assume - # that it doesn't support unicode and use the ASCII bar. - if not encoding: - return fallback - - # Collect all of the possible characters we want to use with the preferred - # bar. - characters = [ - getattr(preferred, "empty_fill", six.text_type()), - getattr(preferred, "fill", six.text_type()), - ] - characters += list(getattr(preferred, "phases", [])) - - # Try to decode the characters we're using for the bar using the encoding - # of the given file, if this works then we'll assume that we can use the - # fancier bar and if not we'll fall back to the plaintext bar. - try: - six.text_type().join(characters).encode(encoding) - except UnicodeEncodeError: - return fallback - else: - return preferred - - -_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any - - -class InterruptibleMixin(object): - """ - Helper to ensure that self.finish() gets called on keyboard interrupt. - - This allows downloads to be interrupted without leaving temporary state - (like hidden cursors) behind. - - This class is similar to the progress library's existing SigIntMixin - helper, but as of version 1.2, that helper has the following problems: - - 1. It calls sys.exit(). - 2. It discards the existing SIGINT handler completely. - 3. It leaves its own handler in place even after an uninterrupted finish, - which will have unexpected delayed effects if the user triggers an - unrelated keyboard interrupt some time after a progress-displaying - download has already completed, for example. - """ - - def __init__(self, *args, **kwargs): - # type: (List[Any], Dict[Any, Any]) -> None - """ - Save the original SIGINT handler for later. - """ - super(InterruptibleMixin, self).__init__( # type: ignore - *args, - **kwargs - ) - - self.original_handler = signal(SIGINT, self.handle_sigint) - - # If signal() returns None, the previous handler was not installed from - # Python, and we cannot restore it. This probably should not happen, - # but if it does, we must restore something sensible instead, at least. - # The least bad option should be Python's default SIGINT handler, which - # just raises KeyboardInterrupt. - if self.original_handler is None: - self.original_handler = default_int_handler - - def finish(self): - # type: () -> None - """ - Restore the original SIGINT handler after finishing. - - This should happen regardless of whether the progress display finishes - normally, or gets interrupted. - """ - super(InterruptibleMixin, self).finish() # type: ignore - signal(SIGINT, self.original_handler) - - def handle_sigint(self, signum, frame): # type: ignore - """ - Call self.finish() before delegating to the original SIGINT handler. - - This handler should only be in place while the progress display is - active. - """ - self.finish() - self.original_handler(signum, frame) - - -class SilentBar(Bar): - - def update(self): - # type: () -> None - pass - - -class BlueEmojiBar(IncrementalBar): - - suffix = "%(percent)d%%" - bar_prefix = " " - bar_suffix = " " - phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any - - -class DownloadProgressMixin(object): - - def __init__(self, *args, **kwargs): - # type: (List[Any], Dict[Any, Any]) -> None - super(DownloadProgressMixin, self).__init__( # type: ignore - *args, - **kwargs - ) - self.message = (" " * ( - get_indentation() + 2 - )) + self.message # type: str - - @property - def downloaded(self): - # type: () -> str - return format_size(self.index) # type: ignore - - @property - def download_speed(self): - # type: () -> str - # Avoid zero division errors... - if self.avg == 0.0: # type: ignore - return "..." - return format_size(1 / self.avg) + "/s" # type: ignore - - @property - def pretty_eta(self): - # type: () -> str - if self.eta: # type: ignore - return "eta {}".format(self.eta_td) # type: ignore - return "" - - def iter(self, it): # type: ignore - for x in it: - yield x - self.next(len(x)) - self.finish() - - -class WindowsMixin(object): - - def __init__(self, *args, **kwargs): - # type: (List[Any], Dict[Any, Any]) -> None - # The Windows terminal does not support the hide/show cursor ANSI codes - # even with colorama. So we'll ensure that hide_cursor is False on - # Windows. - # This call needs to go before the super() call, so that hide_cursor - # is set in time. The base progress bar class writes the "hide cursor" - # code to the terminal in its init, so if we don't set this soon - # enough, we get a "hide" with no corresponding "show"... - if WINDOWS and self.hide_cursor: # type: ignore - self.hide_cursor = False - - super(WindowsMixin, self).__init__(*args, **kwargs) # type: ignore - - # Check if we are running on Windows and we have the colorama module, - # if we do then wrap our file with it. - if WINDOWS and colorama: - self.file = colorama.AnsiToWin32(self.file) # type: ignore - # The progress code expects to be able to call self.file.isatty() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.isatty = lambda: self.file.wrapped.isatty() - # The progress code expects to be able to call self.file.flush() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.flush = lambda: self.file.wrapped.flush() - - -class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin): - - file = sys.stdout - message = "%(percent)d%%" - suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" - -# NOTE: The "type: ignore" comments on the following classes are there to -# work around https://github.com/python/typing/issues/241 - - -class DefaultDownloadProgressBar(BaseDownloadProgressBar, - _BaseBar): - pass - - -class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore - pass - - -class DownloadBar(BaseDownloadProgressBar, # type: ignore - Bar): - pass - - -class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore - FillingCirclesBar): - pass - - -class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore - BlueEmojiBar): - pass - - -class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin, Spinner): - - file = sys.stdout - suffix = "%(downloaded)s %(download_speed)s" - - def next_phase(self): # type: ignore - if not hasattr(self, "_phaser"): - self._phaser = itertools.cycle(self.phases) - return next(self._phaser) - - def update(self): - # type: () -> None - message = self.message % self - phase = self.next_phase() - suffix = self.suffix % self - line = ''.join([ - message, - " " if message else "", - phase, - " " if suffix else "", - suffix, - ]) - - self.writeln(line) - - -BAR_TYPES = { - "off": (DownloadSilentBar, DownloadSilentBar), - "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), - "ascii": (DownloadBar, DownloadProgressSpinner), - "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), - "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) -} - - -def DownloadProgressProvider(progress_bar, max=None): # type: ignore - if max is None or max == 0: - return BAR_TYPES[progress_bar][1]().iter - else: - return BAR_TYPES[progress_bar][0](max=max).iter diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/req_command.py b/env/lib/python3.8/site-packages/pip/_internal/cli/req_command.py deleted file mode 100644 index 104b0332..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/req_command.py +++ /dev/null @@ -1,408 +0,0 @@ -"""Contains the Command base classes that depend on PipSession. - -The classes in this module are in a separate module so the commands not -needing download / PackageFinder capability don't unnecessarily import the -PackageFinder machinery and all its vendored dependencies, etc. -""" - -import logging -import os -from functools import partial - -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.command_context import CommandContextMixIn -from pip._internal.exceptions import CommandError, PreviousBuildDirError -from pip._internal.index.package_finder import PackageFinder -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.network.download import Downloader -from pip._internal.network.session import PipSession -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req.constructors import ( - install_req_from_editable, - install_req_from_line, - install_req_from_parsed_requirement, - install_req_from_req_string, -) -from pip._internal.req.req_file import parse_requirements -from pip._internal.req.req_set import RequirementSet -from pip._internal.self_outdated_check import ( - make_link_collector, - pip_self_version_check, -) -from pip._internal.utils.temp_dir import tempdir_kinds -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from optparse import Values - from typing import Any, List, Optional, Tuple - - from pip._internal.cache import WheelCache - from pip._internal.models.target_python import TargetPython - from pip._internal.req.req_install import InstallRequirement - from pip._internal.req.req_tracker import RequirementTracker - from pip._internal.resolution.base import BaseResolver - from pip._internal.utils.temp_dir import ( - TempDirectory, - TempDirectoryTypeRegistry, - ) - - -logger = logging.getLogger(__name__) - - -class SessionCommandMixin(CommandContextMixIn): - - """ - A class mixin for command classes needing _build_session(). - """ - def __init__(self): - # type: () -> None - super(SessionCommandMixin, self).__init__() - self._session = None # Optional[PipSession] - - @classmethod - def _get_index_urls(cls, options): - # type: (Values) -> Optional[List[str]] - """Return a list of index urls from user-provided options.""" - index_urls = [] - if not getattr(options, "no_index", False): - url = getattr(options, "index_url", None) - if url: - index_urls.append(url) - urls = getattr(options, "extra_index_urls", None) - if urls: - index_urls.extend(urls) - # Return None rather than an empty list - return index_urls or None - - def get_default_session(self, options): - # type: (Values) -> PipSession - """Get a default-managed session.""" - if self._session is None: - self._session = self.enter_context(self._build_session(options)) - # there's no type annotation on requests.Session, so it's - # automatically ContextManager[Any] and self._session becomes Any, - # then https://github.com/python/mypy/issues/7696 kicks in - assert self._session is not None - return self._session - - def _build_session(self, options, retries=None, timeout=None): - # type: (Values, Optional[int], Optional[int]) -> PipSession - assert not options.cache_dir or os.path.isabs(options.cache_dir) - session = PipSession( - cache=( - os.path.join(options.cache_dir, "http") - if options.cache_dir else None - ), - retries=retries if retries is not None else options.retries, - trusted_hosts=options.trusted_hosts, - index_urls=self._get_index_urls(options), - ) - - # Handle custom ca-bundles from the user - if options.cert: - session.verify = options.cert - - # Handle SSL client certificate - if options.client_cert: - session.cert = options.client_cert - - # Handle timeouts - if options.timeout or timeout: - session.timeout = ( - timeout if timeout is not None else options.timeout - ) - - # Handle configured proxies - if options.proxy: - session.proxies = { - "http": options.proxy, - "https": options.proxy, - } - - # Determine if we can prompt the user for authentication or not - session.auth.prompting = not options.no_input - - return session - - -class IndexGroupCommand(Command, SessionCommandMixin): - - """ - Abstract base class for commands with the index_group options. - - This also corresponds to the commands that permit the pip version check. - """ - - def handle_pip_version_check(self, options): - # type: (Values) -> None - """ - Do the pip version check if not disabled. - - This overrides the default behavior of not doing the check. - """ - # Make sure the index_group options are present. - assert hasattr(options, 'no_index') - - if options.disable_pip_version_check or options.no_index: - return - - # Otherwise, check if we're using the latest version of pip available. - session = self._build_session( - options, - retries=0, - timeout=min(5, options.timeout) - ) - with session: - pip_self_version_check(session, options) - - -KEEPABLE_TEMPDIR_TYPES = [ - tempdir_kinds.BUILD_ENV, - tempdir_kinds.EPHEM_WHEEL_CACHE, - tempdir_kinds.REQ_BUILD, -] - - -def with_cleanup(func): - # type: (Any) -> Any - """Decorator for common logic related to managing temporary - directories. - """ - def configure_tempdir_registry(registry): - # type: (TempDirectoryTypeRegistry) -> None - for t in KEEPABLE_TEMPDIR_TYPES: - registry.set_delete(t, False) - - def wrapper(self, options, args): - # type: (RequirementCommand, Values, List[Any]) -> Optional[int] - assert self.tempdir_registry is not None - if options.no_clean: - configure_tempdir_registry(self.tempdir_registry) - - try: - return func(self, options, args) - except PreviousBuildDirError: - # This kind of conflict can occur when the user passes an explicit - # build directory with a pre-existing folder. In that case we do - # not want to accidentally remove it. - configure_tempdir_registry(self.tempdir_registry) - raise - - return wrapper - - -class RequirementCommand(IndexGroupCommand): - - def __init__(self, *args, **kw): - # type: (Any, Any) -> None - super(RequirementCommand, self).__init__(*args, **kw) - - self.cmd_opts.add_option(cmdoptions.no_clean()) - - @staticmethod - def make_requirement_preparer( - temp_build_dir, # type: TempDirectory - options, # type: Values - req_tracker, # type: RequirementTracker - session, # type: PipSession - finder, # type: PackageFinder - use_user_site, # type: bool - download_dir=None, # type: str - wheel_download_dir=None, # type: str - ): - # type: (...) -> RequirementPreparer - """ - Create a RequirementPreparer instance for the given parameters. - """ - downloader = Downloader(session, progress_bar=options.progress_bar) - - temp_build_dir_path = temp_build_dir.path - assert temp_build_dir_path is not None - - return RequirementPreparer( - build_dir=temp_build_dir_path, - src_dir=options.src_dir, - download_dir=download_dir, - wheel_download_dir=wheel_download_dir, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - downloader=downloader, - finder=finder, - require_hashes=options.require_hashes, - use_user_site=use_user_site, - ) - - @staticmethod - def make_resolver( - preparer, # type: RequirementPreparer - finder, # type: PackageFinder - options, # type: Values - wheel_cache=None, # type: Optional[WheelCache] - use_user_site=False, # type: bool - ignore_installed=True, # type: bool - ignore_requires_python=False, # type: bool - force_reinstall=False, # type: bool - upgrade_strategy="to-satisfy-only", # type: str - use_pep517=None, # type: Optional[bool] - py_version_info=None # type: Optional[Tuple[int, ...]] - ): - # type: (...) -> BaseResolver - """ - Create a Resolver instance for the given parameters. - """ - make_install_req = partial( - install_req_from_req_string, - isolated=options.isolated_mode, - use_pep517=use_pep517, - ) - # The long import name and duplicated invocation is needed to convince - # Mypy into correctly typechecking. Otherwise it would complain the - # "Resolver" class being redefined. - if 'resolver' in options.unstable_features: - import pip._internal.resolution.resolvelib.resolver - return pip._internal.resolution.resolvelib.resolver.Resolver( - preparer=preparer, - finder=finder, - wheel_cache=wheel_cache, - make_install_req=make_install_req, - use_user_site=use_user_site, - ignore_dependencies=options.ignore_dependencies, - ignore_installed=ignore_installed, - ignore_requires_python=ignore_requires_python, - force_reinstall=force_reinstall, - upgrade_strategy=upgrade_strategy, - py_version_info=py_version_info, - ) - import pip._internal.resolution.legacy.resolver - return pip._internal.resolution.legacy.resolver.Resolver( - preparer=preparer, - finder=finder, - wheel_cache=wheel_cache, - make_install_req=make_install_req, - use_user_site=use_user_site, - ignore_dependencies=options.ignore_dependencies, - ignore_installed=ignore_installed, - ignore_requires_python=ignore_requires_python, - force_reinstall=force_reinstall, - upgrade_strategy=upgrade_strategy, - py_version_info=py_version_info, - ) - - def get_requirements( - self, - args, # type: List[str] - options, # type: Values - finder, # type: PackageFinder - session, # type: PipSession - check_supported_wheels=True, # type: bool - ): - # type: (...) -> List[InstallRequirement] - """ - Parse command-line arguments into the corresponding requirements. - """ - requirement_set = RequirementSet( - check_supported_wheels=check_supported_wheels - ) - for filename in options.constraints: - for parsed_req in parse_requirements( - filename, - constraint=True, finder=finder, options=options, - session=session): - req_to_add = install_req_from_parsed_requirement( - parsed_req, - isolated=options.isolated_mode, - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in args: - req_to_add = install_req_from_line( - req, None, isolated=options.isolated_mode, - use_pep517=options.use_pep517, - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in options.editables: - req_to_add = install_req_from_editable( - req, - isolated=options.isolated_mode, - use_pep517=options.use_pep517, - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - # NOTE: options.require_hashes may be set if --require-hashes is True - for filename in options.requirements: - for parsed_req in parse_requirements( - filename, - finder=finder, options=options, session=session): - req_to_add = install_req_from_parsed_requirement( - parsed_req, - isolated=options.isolated_mode, - use_pep517=options.use_pep517 - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - # If any requirement has hash options, enable hash checking. - requirements = requirement_set.all_requirements - if any(req.has_hash_options for req in requirements): - options.require_hashes = True - - if not (args or options.editables or options.requirements): - opts = {'name': self.name} - if options.find_links: - raise CommandError( - 'You must give at least one requirement to {name} ' - '(maybe you meant "pip {name} {links}"?)'.format( - **dict(opts, links=' '.join(options.find_links)))) - else: - raise CommandError( - 'You must give at least one requirement to {name} ' - '(see "pip help {name}")'.format(**opts)) - - return requirements - - @staticmethod - def trace_basic_info(finder): - # type: (PackageFinder) -> None - """ - Trace basic information about the provided objects. - """ - # Display where finder is looking for packages - search_scope = finder.search_scope - locations = search_scope.get_formatted_locations() - if locations: - logger.info(locations) - - def _build_package_finder( - self, - options, # type: Values - session, # type: PipSession - target_python=None, # type: Optional[TargetPython] - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> PackageFinder - """ - Create a package finder appropriate to this requirement command. - - :param ignore_requires_python: Whether to ignore incompatible - "Requires-Python" values in links. Defaults to False. - """ - link_collector = make_link_collector(session, options=options) - selection_prefs = SelectionPreferences( - allow_yanked=True, - format_control=options.format_control, - allow_all_prereleases=options.pre, - prefer_binary=options.prefer_binary, - ignore_requires_python=ignore_requires_python, - ) - - return PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - target_python=target_python, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/spinners.py b/env/lib/python3.8/site-packages/pip/_internal/cli/spinners.py deleted file mode 100644 index c6c4c5cd..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/spinners.py +++ /dev/null @@ -1,173 +0,0 @@ -from __future__ import absolute_import, division - -import contextlib -import itertools -import logging -import sys -import time - -from pip._vendor.progress import HIDE_CURSOR, SHOW_CURSOR - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.logging import get_indentation -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterator, IO - -logger = logging.getLogger(__name__) - - -class SpinnerInterface(object): - def spin(self): - # type: () -> None - raise NotImplementedError() - - def finish(self, final_status): - # type: (str) -> None - raise NotImplementedError() - - -class InteractiveSpinner(SpinnerInterface): - def __init__(self, message, file=None, spin_chars="-\\|/", - # Empirically, 8 updates/second looks nice - min_update_interval_seconds=0.125): - # type: (str, IO[str], str, float) -> None - self._message = message - if file is None: - file = sys.stdout - self._file = file - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._finished = False - - self._spin_cycle = itertools.cycle(spin_chars) - - self._file.write(" " * get_indentation() + self._message + " ... ") - self._width = 0 - - def _write(self, status): - # type: (str) -> None - assert not self._finished - # Erase what we wrote before by backspacing to the beginning, writing - # spaces to overwrite the old text, and then backspacing again - backup = "\b" * self._width - self._file.write(backup + " " * self._width + backup) - # Now we have a blank slate to add our status - self._file.write(status) - self._width = len(status) - self._file.flush() - self._rate_limiter.reset() - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._write(next(self._spin_cycle)) - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._write(final_status) - self._file.write("\n") - self._file.flush() - self._finished = True - - -# Used for dumb terminals, non-interactive installs (no tty), etc. -# We still print updates occasionally (once every 60 seconds by default) to -# act as a keep-alive for systems like Travis-CI that take lack-of-output as -# an indication that a task has frozen. -class NonInteractiveSpinner(SpinnerInterface): - def __init__(self, message, min_update_interval_seconds=60): - # type: (str, float) -> None - self._message = message - self._finished = False - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._update("started") - - def _update(self, status): - # type: (str) -> None - assert not self._finished - self._rate_limiter.reset() - logger.info("%s: %s", self._message, status) - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._update("still running...") - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._update( - "finished with status '{final_status}'".format(**locals())) - self._finished = True - - -class RateLimiter(object): - def __init__(self, min_update_interval_seconds): - # type: (float) -> None - self._min_update_interval_seconds = min_update_interval_seconds - self._last_update = 0 # type: float - - def ready(self): - # type: () -> bool - now = time.time() - delta = now - self._last_update - return delta >= self._min_update_interval_seconds - - def reset(self): - # type: () -> None - self._last_update = time.time() - - -@contextlib.contextmanager -def open_spinner(message): - # type: (str) -> Iterator[SpinnerInterface] - # Interactive spinner goes directly to sys.stdout rather than being routed - # through the logging system, but it acts like it has level INFO, - # i.e. it's only displayed if we're at level INFO or better. - # Non-interactive spinner goes through the logging system, so it is always - # in sync with logging configuration. - if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: - spinner = InteractiveSpinner(message) # type: SpinnerInterface - else: - spinner = NonInteractiveSpinner(message) - try: - with hidden_cursor(sys.stdout): - yield spinner - except KeyboardInterrupt: - spinner.finish("canceled") - raise - except Exception: - spinner.finish("error") - raise - else: - spinner.finish("done") - - -@contextlib.contextmanager -def hidden_cursor(file): - # type: (IO[str]) -> Iterator[None] - # The Windows terminal does not support the hide/show cursor ANSI codes, - # even via colorama. So don't even try. - if WINDOWS: - yield - # We don't want to clutter the output with control characters if we're - # writing to a file, or if the user is running with --quiet. - # See https://github.com/pypa/pip/issues/3418 - elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: - yield - else: - file.write(HIDE_CURSOR) - try: - yield - finally: - file.write(SHOW_CURSOR) diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/status_codes.py b/env/lib/python3.8/site-packages/pip/_internal/cli/status_codes.py deleted file mode 100644 index 275360a3..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/status_codes.py +++ /dev/null @@ -1,8 +0,0 @@ -from __future__ import absolute_import - -SUCCESS = 0 -ERROR = 1 -UNKNOWN_ERROR = 2 -VIRTUALENV_NOT_FOUND = 3 -PREVIOUS_BUILD_DIR_ERROR = 4 -NO_MATCHES_FOUND = 23 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/commands/__init__.py deleted file mode 100644 index 6825fa6e..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/__init__.py +++ /dev/null @@ -1,122 +0,0 @@ -""" -Package containing all pip commands -""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False -# There is currently a bug in python/typeshed mentioned at -# https://github.com/python/typeshed/issues/3906 which causes the -# return type of difflib.get_close_matches to be reported -# as List[Sequence[str]] whereas it should have been List[str] - -from __future__ import absolute_import - -import importlib -from collections import OrderedDict, namedtuple - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any - from pip._internal.cli.base_command import Command - - -CommandInfo = namedtuple('CommandInfo', 'module_path, class_name, summary') - -# The ordering matters for help display. -# Also, even though the module path starts with the same -# "pip._internal.commands" prefix in each case, we include the full path -# because it makes testing easier (specifically when modifying commands_dict -# in test setup / teardown by adding info for a FakeCommand class defined -# in a test-related module). -# Finally, we need to pass an iterable of pairs here rather than a dict -# so that the ordering won't be lost when using Python 2.7. -commands_dict = OrderedDict([ - ('install', CommandInfo( - 'pip._internal.commands.install', 'InstallCommand', - 'Install packages.', - )), - ('download', CommandInfo( - 'pip._internal.commands.download', 'DownloadCommand', - 'Download packages.', - )), - ('uninstall', CommandInfo( - 'pip._internal.commands.uninstall', 'UninstallCommand', - 'Uninstall packages.', - )), - ('freeze', CommandInfo( - 'pip._internal.commands.freeze', 'FreezeCommand', - 'Output installed packages in requirements format.', - )), - ('list', CommandInfo( - 'pip._internal.commands.list', 'ListCommand', - 'List installed packages.', - )), - ('show', CommandInfo( - 'pip._internal.commands.show', 'ShowCommand', - 'Show information about installed packages.', - )), - ('check', CommandInfo( - 'pip._internal.commands.check', 'CheckCommand', - 'Verify installed packages have compatible dependencies.', - )), - ('config', CommandInfo( - 'pip._internal.commands.configuration', 'ConfigurationCommand', - 'Manage local and global configuration.', - )), - ('search', CommandInfo( - 'pip._internal.commands.search', 'SearchCommand', - 'Search PyPI for packages.', - )), - ('cache', CommandInfo( - 'pip._internal.commands.cache', 'CacheCommand', - "Inspect and manage pip's wheel cache.", - )), - ('wheel', CommandInfo( - 'pip._internal.commands.wheel', 'WheelCommand', - 'Build wheels from your requirements.', - )), - ('hash', CommandInfo( - 'pip._internal.commands.hash', 'HashCommand', - 'Compute hashes of package archives.', - )), - ('completion', CommandInfo( - 'pip._internal.commands.completion', 'CompletionCommand', - 'A helper command used for command completion.', - )), - ('debug', CommandInfo( - 'pip._internal.commands.debug', 'DebugCommand', - 'Show information useful for debugging.', - )), - ('help', CommandInfo( - 'pip._internal.commands.help', 'HelpCommand', - 'Show help for commands.', - )), -]) # type: OrderedDict[str, CommandInfo] - - -def create_command(name, **kwargs): - # type: (str, **Any) -> Command - """ - Create an instance of the Command class with the given name. - """ - module_path, class_name, summary = commands_dict[name] - module = importlib.import_module(module_path) - command_class = getattr(module, class_name) - command = command_class(name=name, summary=summary, **kwargs) - - return command - - -def get_similar_commands(name): - """Command name auto-correct.""" - from difflib import get_close_matches - - name = name.lower() - - close_commands = get_close_matches(name, commands_dict.keys()) - - if close_commands: - return close_commands[0] - else: - return False diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 7cbc2bb7e8a25fa80b18809eafafefcab00e72a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2966 zcmd5;Npssa6ecNZu@*0h+r(L!W>p%?O|vyiQzvp9yJ;LxJ!u1E&8QaN!Lh; zZKJ$EXZ&)jtYk%6@vE&W$_h||nSG;GBY7y38dRVPwf$VjfLTOyFb@j~9YJ&y7U4aG z-bZu{j>D2dClH;4Q*c_LGl(Yv`TdYZTXjQJUN9hxz?$bqq8vCrfhg`%g6c<}zuJCfH#eR%pV?o&+}hgQdWxgD zN5KF;#b&}TDrsjk=!8Sd42WzlfuL99gM31P&N+$YSKX z*ki;eLBy?2$b2Vi2$Om|8lIf8j1-E>7uaS?9GBpb1(1pN!o8_XQYb1r*k(*uB|xUc z5-$uaryU+@d_&~j9&vYvr>2;xq@voCN*Vo~uL$!xgF{TUdd_Q^`97wb*QUe*(kB6s z!1V~GM*(Z1<8_A@rY)w#F~iAWAQqdGFkAf6b0?7HMMKx27FLthrC}Sp33oaf*W$!s zZf|Os6S1i6D7B1zDS_7ZV0%*r@*v96Q4Ts|x}&5N9VI^*+eNI9K5-*uCRV<*8@GO$ zTYEi1&}6BM%nD6qR#H*@T29HBFFcMt3JDEn91DGG5XS7CM8v%5IlMPDZ=_IEHn7cD z&tnIZoM0Gvk8msOWc#W@S+O0h= z>Z#!_1}m`SN#9Tec(IrgiDG*0*G*ANz0GZqcg;+42T`vrYDw2lE)P-clE{f7Rxh#3 zxF1p2-E&x%i^|01f_ZUpxv(orE1jJ!V=DzwOjrFyV>eLkujWeR_g65Hmg7L)Bm|aK z#xLKE+k+eJ0hO|qgL`QuGkV3wF)y<1Mt>k?UF9G<6}FL>t3N>bS-p(EMT6bKv3KH> z!vPcDrc}O-jrt3u`TAJbF&b}-x7t`6=_4)5y)oZv7$=MyYm5xgm$V&CUie^QjPk=1 z%`|PLhbrmk#iX~yiFa#0jy%d6(V&k7#bnxx zLJA5J{QFM@^%`vlosjN=6(z5%7`1B^BxT;j?qrrQwZ+ndB&8lor}AI1F)O$&eI7Sw c>Q%j(E0+!3)D6whjlWIvf7JWEuv)791M<758UO$Q diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc deleted file mode 100644 index 9328c2e0c4ee4bb062921286f3da6b56e7d6746c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4394 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc deleted file mode 100644 index 28f940accab61f359ab55c351354eb48c48f63d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3017 zcmai0&2HRA67J^Tj7B3Xc7E1yc7u+hgBXOPC6^&+2GLn-Q*!v!&V_st)qpy2f>>KPJk}A$fGqR+F1e?{>-PP4!eO2V+xw!^` z>&cJ*3SZ3<@^9=+Uk-G>fJZ%nh7(Rx(xYukQMOX6ZB=i(ZNuA6ou1ovt1&0_dbM^9 zWVc=C9g<0}Mv;l$38e>QS>cqZc9wT-Vgx7Ihm`gV1REiP5v@SBaT``fDvi-(6eI_iG+ z;nU%8fqj2&@#${kcQtzrSFbKkZhNo$b$<6cJ~^y?8WyVIa;fSy7}1mmpo)2Z*l(cmn6@;?mN{Zm`09|0;AZ#dWmJ z%G2}kUWsn3Qx^Q~HxVr_M>OmtYVVYP0s)>vhcP7}ROt^>Y-39hPE3q6$uOcmTUfYy zNyRa?bjjI!k={dFnU0c7u^?eV@S1Jyvk^Nhn)`s_c~Vc{Kw6)=dI3+ia^62JlWdo% zB26^=o>kk57eJkkt5 z+-j|HxKP?Sh)v%O0*D9L?@JF%_WyXLEu04KVBlbSN7iuq)m!5{iC98xTvb98BqC|* zVVGoz4ntFqdpyhwtxO~0l>`AWUJ*$pqshJ7GIE|DF!=K6j)|Yj!ScV)9%B+auXMzX&dqSka=jG19?VW=Z$CkkjEo2s@ z%VTyZ6vp4NR&gNT0MnnrqdtX(&>NO#In*K+9pC@=yx-~9`nT53OoD_QY@MDzK4m*v zN9+;MHF%VUMw4TDLWVYy>Lt&qECd+H`BWenhzQ zik{G+t7mkhTN}95sQbz~0qAHXvOrN zxIn19Q>k~87XrTX_~k#BD;9W-`Lc~icng|c$c?AXAtdpD{(=0%dhWm$6u1+}TQKZf z#%g^m@eio#kD7O(YZ`abL}`r1-N(>ZXx1YZ>H8Pqlx5bsQ+@Q*T@X&!8T_Gf@KXx= zc%%Q3YOnsy^{uUqtv|DG^OE&SrC9;IVTZ#;-(gS_9{Tg<#`xR*VB=x9y|(pW^U=0( zo{0kmmf*ig@XC^@Yw?5Lmr-FnF1X0FvEdiVcu-oPtV{ITxCH`g=D)nRy?*-30A`J? zDr=fUUKn>@CR!M$nD~|2vf^qEBbSye;(#G{DZWCE`oI0|{vJ;n%2c@_W1qlS` z1!!9cmFYxI^5jnX-kD0B=|iSZed>E3`Vabox3*9D3rQ3AI}4H~RXV+h#@?`daQ5u^ z&SiaLYO18+@8&0ec3*r()BZu7;XebNpWul4inU^^R4cV6Y7=VA3?^GswJFuMg6Y;wZKhSOm6_&gy9d14Jytt- zQ4$ovm@(?ABEY|O)qg9!$a@e>XMiiGpHv-SsXw;DQ3k%)Kg+kJcW8%91>5Xo)L$|5!B^RHAAZ%fJBaFb0eGW ziKTvmYuY>Yu-^2XAZpYD2eNXSL9~kIh$yP1l7qjM&T1o3-}Oe;C&}lGj33&82J{O zYSE=NCyYYRiPoI?`A+P~)2Mr5B#F+?$50WcEV{JE*jcZ) z+g=D#YHbp!irCI&yt<`G32&|536iSnTu=Y5YC5G8r1s9O1^VcG)F$wpzpa$uKTNqb zKTjtNO<2h5`F1^7$6D$=R;Tgwamb^mIDQ%(86BxJdZgngtAl<_wZVpvOTaDQnZXl3 zK#^z(>uNiEgLhe%|B8`W>T0gu)i#U`Q!v4W4#Ng0KQtNMs8Il#zziS{k4^y4G&(gh z3UI5@@?g~3ErHAB$aB-kGOa~RcALvKbxe)xs!oaMX8w;fZR+$PD4dNoEneVJ-_j z{m6`UFK822xx!}?d993RR#L3FiR^ekOuKoQ782UBB9-~VSNaPZ9VrQ8!+RcMWrzVu%22T(+)mq*ass`~c3nU86W7hA zMpk8Zqa|EGA-_}c?T^y#~^Ci{3Y#M!+ zM;{^tQSh*cCq4|3LYwIUl7J&^L!n2o-2d$=sg3QLzsh*=!o@xzx(1W+la`8p*66YBr($CeRbf z%p&&c*xW|s0~&E8@nuQ6lFhing95kwFvqL3iRb62FzNkNpHUZn%#(*{%pjH}MV^&{ ze3nKEIlN-EFtgX;8v{?qk_@19@CM|Jcy{>au#XdPvft>ou4v(0 z4jq7l%cQFd>j&tCpFzeh~2;E74pP2lx*`F+04wmC3rblI=@9b=^@ zMv^6L8Lz&a>6_kGW-9I4FXz$%=@YC|`}`+F*Fs@wmSOxeJv&xx`!u4upu*GmJQ{sM zBU~enMXU?T^c+P2o@cii31JuhdXK#e{N6zlf(^4}VmOL3gTfDZQ57>)xFpk!f>6)CQrgic1l{eqGEN9jD%BAZ|@+oTS z^>9nlnPht4g$jPKA%rS=Xt8`|QVx z=5ku1sQDHd=-auPT?UDipNMh1%V_4CE7F#8+|mZ+RVwyvy4)MWA{g~(I4>i_BY3-dHTZGqZ)O2BfBJ9FwjtPyra7uJ}t@+M)xi>N-9!0@KIJxbN`3hnauGGkkc@kKNp3|2?uXvJHbUu8j_uM;HX9>nY%#whh%2 z+NLd!Lk;1FK4R%?V(gj(y(XuS3t`f$2$PHr3xU}N!X%_g=^SSB-9p#gu=mue_p~2S zKxTeu_5(5nS$#P@u^4p%q0*8;yx<^}l~Eg63ydQfsA_tumj>ak0aNfyk+t9T@U7d3cj!qD*S6EM5|+xJOw<2Yz;>mHd;GMzY0#10%W#H(E&2^;boz^O5 z>ptXDMxqu9wuuoH3{v!wPLsvhWn}jNms5ZX2UyNB^x@z14WsAnVB-^0sDsI~mY!cr z&)oqy*A=+oC#ee;h(eGX;ziIkR{mO{RX1_wJ4pr)JrTK zrO{Pra2|XU>8!YPzu~ErR(>D6%U7sSa%H)q@3TT=ul|ZBE~C&8I#1(=z?$)IEF(QR z)*g*9-wiVQ{Xc5cqa=6%4Ft?EADcy4rWRC`B?zlGEtnJ)UmP!!f%WSpWR+REnNVq%o0VM3k~#?0+-%Zy@8F8D_om>wB5Gjx zpx+E}VdP5hPRB=m7rY|LjByRD?g`}U;6#OVDuR*Z`z1L@NsdI4Rm!6WI#IQOY^rx_ z(eQ%6b%&7S&=j>%xtQ5zQy>NjK0*puq6rSeo(pajwn zn@XVaCRSz7;ku(bxbCPn0>8QneTIKm*Zh)HVceuRsVAKn({P2Qa!!>wX5ZOIZunY5 zrJgD%&co=#qjQ0gT=(PLG39LmRo~~2bhz-wBx#^iIw>(Sb zC9kA%+bbhCV>@v?N6oR~N>cTzs$7c8$%Hql%62@JOncL+T#nBqGv16UJMr0M)|*x3 zN<5d$d-JMXjTe$dZ&8&e;&aK8x1`FG@p7`_t>{{~!v6<*PsOXrdGEaHn~uMeT<|U= zuXwK{uIDDNdatVXGx5dbHSaadF%K?`lh$j%{u zlP$4jh zwC+T?kj_ukF@jiH>rqo+sQpH;-GwaU5iwR|F^qF<3L(_-fo9k39A^4LjUM`u2bL^G;- zRkwA=unb4%E?UM2WTIh2pifW{+739aQd3xm;5#!8&Aui|J#AnAda187lUdJzgai9f zTSr^pI3f-RR$?}K4eHs~L8@{?mVwxmWxQK0^165;nowDz-w<*4(2`$4(gHiabg>uq z*|j;CaG)J36yh`nGnci0H6B`6-TKzJb?aN*{f3s~lmK(3T=1xktQ|+#E0%ca#0#J03{vM7~h7D2QinUfGT=$EDfu(Yyvn92&S&WK)^ z!$?n<-kD=`P|N6BvZRKbJnh0uPxU=IIpJS3Yyi^GjXzm-)wFf{#f-&&g!VC55+muJ zN^ajofnfMdNv|+=Ag_nIf*xQwfTMz<0$izaiX((_g{>JB6t*1VNr9oG3qbM+eA3uT zj~Y1%8mBXC;8WDMiTZC1?nyc+Wl;71FNn~(fXKxmL`dM4Nw@$Pl#OL=YX})r!Ck+m zP+p*hzlG_;QqSv_Od z1J{;-7 zW$47r-3-Zb>z;c`xa;4#^|aW#|1^9ecmS79xh2vrnq^5f*GjS!i7?3(0hL4?xi;vW zJ7y*Zr_U8jUKqg?gaF5<&V84CEFxL8)i)I^^H%!87TXm__QgXYT90(xK6}1r%@3CRQNIfQ!7V z@%Er!-?ey~+5Ix~1nmAVVe$JWqL6aGEF3WB?=Z&%!)E&qts*KtXJ0Y(;V*h+{_o7$ zF`?=!U+KqpIbxk+T($8HA)`<`Q|^@_;#7fKcLCuj9J)y9p`evhE6m{~jKBY0_s8{m zz528FBAyHPsR&wr93_$HyC~+QNFJwk_md#c-D}stsm&}`%8WW(u&MqfOkrg-tybj( zVd;?CrWNF55hnVr2ohA-S2IRwBr?j((6S052$=-0Rb+V(P4l1Aa#Ldgw6thtZ>Ct8 z^i9zXz;(8^q9@W!@|HJAgNn<9Oq!^j1X4wbAr1RCY?6~3rNM+ax&vcE8l`H?;9Ep# zx@gyDkQ*-y)A*BZ@okJBgA`d!a%f0SbAd!?kV+jg2{3`d=OK|~QYg-bwI<0W_fHv) z>7JhdfWZMI_lDUm^Ix=IX~yCZ*)c;R%LCcs-{M@u~T{ z82w!LR+WF1`(ir~eg@3&h=qRPQxz;2x!eCqn-IlRM5c8wHUod)YSSCT%R(_}7b|s* zt8UE(T;PI`f{|vxmIq`o?d(#9$2K{pKl|s#f z|Ar?#9nW_Lp6*Pqq<9VlJaaso*{qC5tMaeF5YGW;9XYv9&m)89rS7Gwi{E;LAUN1_ zNh7vgq8q)-;H{#ry1R=ibKTe5JZrf(2ZD9`{utYd<@BAQ!@Yw76!E(7~$oXcncB@O|mv$;`)L za!vq{%V6L5I~jG-gPOFJ|H$!Ll0r)WQ>xu>@vPJ44{5SRFvdHWm51?`wD8)NOJnyj ze}c~E&`-YKjG@Bd*eXk`@b?&fzsHx8-qiG26|_$4-G$>Mt`Cpf9CD5ZQ<-Fa4PXAh zNRImx43AFxARH_%>@0cYgR+IPJt&tz#xm@5G0H~G8P&?7a!?)B9L$RnR3%WBURa*46`DlmAa(f#fH?I?E#FLo}9SsL%TNf@NU1^5aewjfP)cRh1csGtrR z4Vv^g65DRj5m|vyHJrFhzAqk3U6>6)Ww9M%3Pacx#rahi{Y_dSbhD0VcZ3={fQOrH z6>ARLw3#s+th+pDrRN@sO6*K!i|-o5sT{weG_4 z&h?FAiS_a3QAl4quS~EkKMr_`o2hq6J^?WE3zU3>L{^U|B4ol${=&{=@8lU zsdbZ*f1>1s2X69C`UkY<^k@a6PeFt|sng#y{_u9C*$68pb=#QL=@0GX7#P!Nag6TF zn3BL^a9N<*D9(av!;8Wo`1j?c?>|JmH|Qz*KFgXIQtD7d1eMlGGalj}3@ThkFpxgt zq?!0{kjSZl;%bI*JXBulCcmH|N{x|L{cn6qjlpfP5Ca>Nj?%WZ@6%DXI--Lud`_mF z{~8G%d+?G^OsA(G#cxTXF?=j3h)r6~n>*HA9{{dk2q{4RT^e&%jTt`W*PC%vsPqe` z+UuJ^9{K}8<@BuKoj*P3=zl4NGx?Hr5F&_9j+I!LD~`)TGDe5!2q=#F@S3FJ<ROu-g=s?Lh~Pu*^noh}?a?U!oGmCWDaZtPH%>M<|l}~*D diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc deleted file mode 100644 index 0c0c5913fcce572a14391f31b849ab0e0577c338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3890 zcmbVPTaVku73NJ8MP2r0d+l5RB0!o7sI&>vG-$D17_iZzfMEo6QUnT8g3Fm*am|}& z$lYimJ*`ncIY9rx?qmK&f5yD_ssEr&)4JawskO9j^H32S&6zWEX3ja^Idk|$zwc`J zefg)q_|LaB?XN_v{wxsp@yc(}FpcT4mgo~*r@j#z6QlY!Cno;Q*h*THR>iYoJ84ha zRlgNGNoUeY+=*M!cHB*RlU~(t$Ngk586+E%jbwAOS&cdIRLG)squ+WtL%Rz`v+JS`q%NfM+?_0FPV>W488(lW=&U0NYt&+`irgipB` zn#$#=ECu&jB-9|yL=wc&IrsCRm_m$*aGtCz^0I)K{^vZ&A7Zbt$iyt9gRlO~hL9hk z!?lUdG?-S0S&fPHLOar#$*kwjq{VI4V)k?GLZ7r>XqGl{V2HNbc$l4~aTc&fjo^{4 zX|9LglHuhzc5uw4cO>}{ zstxie_kvhvo-A{6tMpi-B^`~_@ZMWFAT*0&F5ml^cQ%c}DeZq6Fkr>Bv~Qo;eT5Bc>@oYl$(Z!Zn%dGAB=vG-MjuCKlQl|#I?(t-C? zWAagD)Y0|)@wk@xrlgTr6IN^V{|MSY4dt~1;F<&Pe{Z@Uuepoh`=iqvFOkRht|x~u z&-Jf`9;KBHyz)Lcg;wZu?ZP-Q=K9?D7U^TIotO)AZeChN>(ai`u4t^L+G~`vMs?OG zca7?UzkG@t}G zLWG^~zA;p%8r53{O_irin)~jXNg+ys`+YDE#zRY4w2Nvdya-MMq1uce1!Y_)Ys%wX zkgJF9s20MK3(*6m9N&-9sPKK|An*Esx>Rn!svb@#D8H$0h-8fPiM^!itptr!ox?JU zS#`p8n)!_9QVovd>@bK)7-ezQ0pk!Vi<#uTn(r7X$gBW2;9lFE2`CT^46+*$w`^*dd4 zeB4d}l<>dPzJIV+B>5f^<)}<4+i*5In{pnHepw#QK0cfwLZf^SzA3m!gLp5jZ#lWQ z1jRU?iCfs@1HAGf8cp9eY-6DR$YWT#p;eD=-~shd+i@|9=igRqpr7Ae0<5`?#!GmF z%ZrY78sP2VeSlZ~fQIRF-Pevaw0dD&nsdDh7Hh7bv@VF(D(t#XL2}t9{=zJrxqhKn zLDWHdG3ORDUYd&*X1e*8XuCaaVPk%;=wBewEZW6@M&~wyRA<&pYvF*qF{k9zLV#L} z4gzv>4!QF-xq87jr0k5MBHO`%I%EPCAb6a!fS5TDS>)zV! zU_b`J;0a!N7Y!V)eZ9FLgKC1Dt^e70WJF8e zO`7!^*9$7X)$PW6O)=ruo>C6dQ&pvkdo-($(ghAfhAsFvg=mxXE-^N5)UQ(At5VcT z`t_IYRsDvAgb3fNL0u^?{j4^r_T|W)G72lFt2R`kxym}pqEwJKm3lTzIEgZ@8kcR6B#Pst7m@Re=3 zy7S7hEZsHEcm4~ch8?;Z38uIjUEfbKR>sut`Tnyqh#OAZ2dqO3w@Qh~tunG8vNhDr{BeQwZwSExdz{B&$QUp4IMsVCdEOaF@0|Dhv8p@dd@7YRB2}G0JH1 z6Ht>a+!EvKTVfo>Q3c+~J8z7SUw>BB@O<~pDew<~Sba_jDg`S|)QyRlG^UBo=TwDQ zb$4A@Sw#4#NFo_lK~l#IDX4B7te#k#U4Q77(KnGZ{oeB132b?03f-7WdHyG diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc deleted file mode 100644 index 1f65dc7b65086ef17e50196d1d717ed63ca79b42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2867 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc deleted file mode 100644 index 9a94fb650d2cd0805e52b02bfbc18294f21c216e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16474 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc deleted file mode 100644 index dfe0bc831dd720c4e6cbb59440767ffe8e1ded16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8470 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc deleted file mode 100644 index ceca820b17600b04273ca5d1470d49afd463dbfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6324 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc deleted file mode 100644 index 6b2066bd1f3d645d0d6ea0c94aed5c7070b4ba55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2786 zcmZuzUvJ~a5nqxkl9HwKzXWZOrrlneHUc6UXpjO84nfddP^3i|sb3*zdzo3uvf?XcE|#-1v$H$D-;5s*20a4L zUqAn6{8^unf8odG(}9oo;8hD4IN?rC3MXPfL~u!?UB2~*4Ez6v z{mIZV+sTot@>RWl{(b2Jcrzk(3;!`;UZDSyiqif6hM5 zN;LbhR65D?M8nz#QdSa#dvzj}h^07dGARmCYBhAt%h^&D$8}aOt&56h69^c0j^S^XmAsm%6wkQ%c&iWfCQJm098MyaJCVoTh<-sP z4)-{H5=I@~;rF|Nu%c3$t=tKIW5)heRW7juj<3YrTyaZDw@|J zt;g)|)$-tx?A3w}~wqr!`0+IqL`W-i3D?UiC2ynrNpbm+pz% zI<5O9@UJB&-U;OncM$`}1QEc4D`4GfB}5+aE#BvYE8rzaJ5POn2UnlD$T>jC_Jf5x zl8eD;v=Nl)Z+s}@<1LlkP`uK`$qjaZI!sT+O@QQm z*z(#KP!|%)8U=<$lk2QT=w$^!a@aAH3#B1~6tQIjE+z@+m;e)ho=8KdBCp{H^F?Pg znhRw-9C}JuQp8#|V)2{%Rrzbp5_QTZm1JpEPBK|o;<0M7fp9KzVG%qYdJ^wl?%=SG z1EvNT)lm)LMQ*{D3F9~`Gabh!ObZ^vX<*-k+Zo2{+e#qKKA=xXjS9&1V_7xz&@)tt zd}3%KkCkyxXWuxc8^>v$C>6)wknipv=%PLVHjbJSQ6>0jHWeZt{jNEhzjZXvaqR#i z0L+(3evmF}ojO=E7FZ;I1cBa#SN#$O;_NxT;}X|d|Gx9P8mAU3=OWO48vwYWv|V}DKGZ=Q-m-sq%l_fndo5L8>5zLT-3igXOY)_2 z>3rtsElyi{>hsPOl7&9)KO@#F#xVe|NQ7Uh*ZB zcbEHTdTxA#V5WyX`BU_Th?B44@H!09E?kC+A@Ums*wKs!auZ@#;}@j$k)V7*b8x6q+IO8fg(`e3++n@$=H9TluyP%y6m zF2*qwSzgKUviAU5#2(jq55gPV;Phl)!&Ct8yVJx_R|QCCJKJ2mb*yKmMW4 zO}n?CiFSXu4CWSAxAzD67@(`5FsD$VmBpvU-t7(S8OBAXQVT$P2OC#*gMskgG7<0M RQ506}z6(ER`P-p=?|Xj^Hd6oq diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index e47fb27fcf71188c013c8715a9c51381e3bac7bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5072 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 E0KabA can be a glob expression or a package name. - """ - - ignore_require_venv = True - usage = """ - %prog dir - %prog info - %prog list [] - %prog remove - %prog purge - """ - - def run(self, options, args): - # type: (Values, List[Any]) -> int - handlers = { - "dir": self.get_cache_dir, - "info": self.get_cache_info, - "list": self.list_cache_items, - "remove": self.remove_cache_items, - "purge": self.purge_cache, - } - - if not options.cache_dir: - logger.error("pip cache commands can not " - "function since cache is disabled.") - return ERROR - - # Determine action - if not args or args[0] not in handlers: - logger.error("Need an action ({}) to perform.".format( - ", ".join(sorted(handlers))) - ) - return ERROR - - action = args[0] - - # Error handling happens here, not in the action-handlers. - try: - handlers[action](options, args[1:]) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def get_cache_dir(self, options, args): - # type: (Values, List[Any]) -> None - if args: - raise CommandError('Too many arguments') - - logger.info(options.cache_dir) - - def get_cache_info(self, options, args): - # type: (Values, List[Any]) -> None - if args: - raise CommandError('Too many arguments') - - num_packages = len(self._find_wheels(options, '*')) - - cache_location = self._wheels_cache_dir(options) - cache_size = filesystem.format_directory_size(cache_location) - - message = textwrap.dedent(""" - Location: {location} - Size: {size} - Number of wheels: {package_count} - """).format( - location=cache_location, - package_count=num_packages, - size=cache_size, - ).strip() - - logger.info(message) - - def list_cache_items(self, options, args): - # type: (Values, List[Any]) -> None - if len(args) > 1: - raise CommandError('Too many arguments') - - if args: - pattern = args[0] - else: - pattern = '*' - - files = self._find_wheels(options, pattern) - - if not files: - logger.info('Nothing cached.') - return - - results = [] - for filename in files: - wheel = os.path.basename(filename) - size = filesystem.format_file_size(filename) - results.append(' - {} ({})'.format(wheel, size)) - logger.info('Cache contents:\n') - logger.info('\n'.join(sorted(results))) - - def remove_cache_items(self, options, args): - # type: (Values, List[Any]) -> None - if len(args) > 1: - raise CommandError('Too many arguments') - - if not args: - raise CommandError('Please provide a pattern') - - files = self._find_wheels(options, args[0]) - if not files: - raise CommandError('No matching packages') - - for filename in files: - os.unlink(filename) - logger.debug('Removed %s', filename) - logger.info('Files removed: %s', len(files)) - - def purge_cache(self, options, args): - # type: (Values, List[Any]) -> None - if args: - raise CommandError('Too many arguments') - - return self.remove_cache_items(options, ['*']) - - def _wheels_cache_dir(self, options): - # type: (Values) -> str - return os.path.join(options.cache_dir, 'wheels') - - def _find_wheels(self, options, pattern): - # type: (Values, str) -> List[str] - wheel_dir = self._wheels_cache_dir(options) - - # The wheel filename format, as specified in PEP 427, is: - # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl - # - # Additionally, non-alphanumeric values in the distribution are - # normalized to underscores (_), meaning hyphens can never occur - # before `-{version}`. - # - # Given that information: - # - If the pattern we're given contains a hyphen (-), the user is - # providing at least the version. Thus, we can just append `*.whl` - # to match the rest of it. - # - If the pattern we're given doesn't contain a hyphen (-), the - # user is only providing the name. Thus, we append `-*.whl` to - # match the hyphen before the version, followed by anything else. - # - # PEP 427: https://www.python.org/dev/peps/pep-0427/ - pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") - - return filesystem.find_files(wheel_dir, pattern) diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/check.py b/env/lib/python3.8/site-packages/pip/_internal/commands/check.py deleted file mode 100644 index b557ca64..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/check.py +++ /dev/null @@ -1,51 +0,0 @@ -import logging - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.operations.check import ( - check_package_set, - create_package_set_from_installed, -) -from pip._internal.utils.misc import write_output -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -logger = logging.getLogger(__name__) - -if MYPY_CHECK_RUNNING: - from typing import List, Any - from optparse import Values - - -class CheckCommand(Command): - """Verify installed packages have compatible dependencies.""" - - usage = """ - %prog [options]""" - - def run(self, options, args): - # type: (Values, List[Any]) -> int - - package_set, parsing_probs = create_package_set_from_installed() - missing, conflicting = check_package_set(package_set) - - for project_name in missing: - version = package_set[project_name].version - for dependency in missing[project_name]: - write_output( - "%s %s requires %s, which is not installed.", - project_name, version, dependency[0], - ) - - for project_name in conflicting: - version = package_set[project_name].version - for dep_name, dep_version, req in conflicting[project_name]: - write_output( - "%s %s has requirement %s, but you have %s %s.", - project_name, version, req, dep_name, dep_version, - ) - - if missing or conflicting or parsing_probs: - return ERROR - else: - write_output("No broken requirements found.") - return SUCCESS diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/completion.py b/env/lib/python3.8/site-packages/pip/_internal/commands/completion.py deleted file mode 100644 index 910fcbfe..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/completion.py +++ /dev/null @@ -1,95 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import sys -import textwrap - -from pip._internal.cli.base_command import Command -from pip._internal.utils.misc import get_prog - -BASE_COMPLETION = """ -# pip {shell} completion start{script}# pip {shell} completion end -""" - -COMPLETION_SCRIPTS = { - 'bash': """ - _pip_completion() - {{ - COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\ - COMP_CWORD=$COMP_CWORD \\ - PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) ) - }} - complete -o default -F _pip_completion {prog} - """, - 'zsh': """ - function _pip_completion {{ - local words cword - read -Ac words - read -cn cword - reply=( $( COMP_WORDS="$words[*]" \\ - COMP_CWORD=$(( cword-1 )) \\ - PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )) - }} - compctl -K _pip_completion {prog} - """, - 'fish': """ - function __fish_complete_pip - set -lx COMP_WORDS (commandline -o) "" - set -lx COMP_CWORD ( \\ - math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ - ) - set -lx PIP_AUTO_COMPLETE 1 - string split \\ -- (eval $COMP_WORDS[1]) - end - complete -fa "(__fish_complete_pip)" -c {prog} - """, -} - - -class CompletionCommand(Command): - """A helper command to be used for command completion.""" - - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(CompletionCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '--bash', '-b', - action='store_const', - const='bash', - dest='shell', - help='Emit completion code for bash') - cmd_opts.add_option( - '--zsh', '-z', - action='store_const', - const='zsh', - dest='shell', - help='Emit completion code for zsh') - cmd_opts.add_option( - '--fish', '-f', - action='store_const', - const='fish', - dest='shell', - help='Emit completion code for fish') - - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - """Prints the completion code of the given shell""" - shells = COMPLETION_SCRIPTS.keys() - shell_options = ['--' + shell for shell in sorted(shells)] - if options.shell in shells: - script = textwrap.dedent( - COMPLETION_SCRIPTS.get(options.shell, '').format( - prog=get_prog()) - ) - print(BASE_COMPLETION.format(script=script, shell=options.shell)) - else: - sys.stderr.write( - 'ERROR: You must pass {}\n' .format(' or '.join(shell_options)) - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/configuration.py b/env/lib/python3.8/site-packages/pip/_internal/commands/configuration.py deleted file mode 100644 index b801be6a..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/configuration.py +++ /dev/null @@ -1,233 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -import logging -import os -import subprocess - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.configuration import ( - Configuration, - get_configuration_files, - kinds, -) -from pip._internal.exceptions import PipError -from pip._internal.utils.misc import get_prog, write_output - -logger = logging.getLogger(__name__) - - -class ConfigurationCommand(Command): - """Manage local and global configuration. - - Subcommands: - - list: List the active configuration (or from the file specified) - edit: Edit the configuration file in an editor - get: Get the value associated with name - set: Set the name=value - unset: Unset the value associated with name - - If none of --user, --global and --site are passed, a virtual - environment configuration file is used if one is active and the file - exists. Otherwise, all modifications happen on the to the user file by - default. - """ - - ignore_require_venv = True - usage = """ - %prog [] list - %prog [] [--editor ] edit - - %prog [] get name - %prog [] set name value - %prog [] unset name - """ - - def __init__(self, *args, **kwargs): - super(ConfigurationCommand, self).__init__(*args, **kwargs) - - self.configuration = None - - self.cmd_opts.add_option( - '--editor', - dest='editor', - action='store', - default=None, - help=( - 'Editor to use to edit the file. Uses VISUAL or EDITOR ' - 'environment variables if not provided.' - ) - ) - - self.cmd_opts.add_option( - '--global', - dest='global_file', - action='store_true', - default=False, - help='Use the system-wide configuration file only' - ) - - self.cmd_opts.add_option( - '--user', - dest='user_file', - action='store_true', - default=False, - help='Use the user configuration file only' - ) - - self.cmd_opts.add_option( - '--site', - dest='site_file', - action='store_true', - default=False, - help='Use the current environment configuration file only' - ) - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - handlers = { - "list": self.list_values, - "edit": self.open_in_editor, - "get": self.get_name, - "set": self.set_name_value, - "unset": self.unset_name - } - - # Determine action - if not args or args[0] not in handlers: - logger.error("Need an action ({}) to perform.".format( - ", ".join(sorted(handlers))) - ) - return ERROR - - action = args[0] - - # Determine which configuration files are to be loaded - # Depends on whether the command is modifying. - try: - load_only = self._determine_file( - options, need_value=(action in ["get", "set", "unset", "edit"]) - ) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - # Load a new configuration - self.configuration = Configuration( - isolated=options.isolated_mode, load_only=load_only - ) - self.configuration.load() - - # Error handling happens here, not in the action-handlers. - try: - handlers[action](options, args[1:]) - except PipError as e: - logger.error(e.args[0]) - return ERROR - - return SUCCESS - - def _determine_file(self, options, need_value): - file_options = [key for key, value in ( - (kinds.USER, options.user_file), - (kinds.GLOBAL, options.global_file), - (kinds.SITE, options.site_file), - ) if value] - - if not file_options: - if not need_value: - return None - # Default to user, unless there's a site file. - elif any( - os.path.exists(site_config_file) - for site_config_file in get_configuration_files()[kinds.SITE] - ): - return kinds.SITE - else: - return kinds.USER - elif len(file_options) == 1: - return file_options[0] - - raise PipError( - "Need exactly one file to operate upon " - "(--user, --site, --global) to perform." - ) - - def list_values(self, options, args): - self._get_n_args(args, "list", n=0) - - for key, value in sorted(self.configuration.items()): - write_output("%s=%r", key, value) - - def get_name(self, options, args): - key = self._get_n_args(args, "get [name]", n=1) - value = self.configuration.get_value(key) - - write_output("%s", value) - - def set_name_value(self, options, args): - key, value = self._get_n_args(args, "set [name] [value]", n=2) - self.configuration.set_value(key, value) - - self._save_configuration() - - def unset_name(self, options, args): - key = self._get_n_args(args, "unset [name]", n=1) - self.configuration.unset_value(key) - - self._save_configuration() - - def open_in_editor(self, options, args): - editor = self._determine_editor(options) - - fname = self.configuration.get_file_to_edit() - if fname is None: - raise PipError("Could not determine appropriate file.") - - try: - subprocess.check_call([editor, fname]) - except subprocess.CalledProcessError as e: - raise PipError( - "Editor Subprocess exited with exit code {}" - .format(e.returncode) - ) - - def _get_n_args(self, args, example, n): - """Helper to make sure the command got the right number of arguments - """ - if len(args) != n: - msg = ( - 'Got unexpected number of arguments, expected {}. ' - '(example: "{} config {}")' - ).format(n, get_prog(), example) - raise PipError(msg) - - if n == 1: - return args[0] - else: - return args - - def _save_configuration(self): - # We successfully ran a modifying command. Need to save the - # configuration. - try: - self.configuration.save() - except Exception: - logger.error( - "Unable to save configuration. Please report this as a bug.", - exc_info=1 - ) - raise PipError("Internal Error.") - - def _determine_editor(self, options): - if options.editor is not None: - return options.editor - elif "VISUAL" in os.environ: - return os.environ["VISUAL"] - elif "EDITOR" in os.environ: - return os.environ["EDITOR"] - else: - raise PipError("Could not determine editor to use.") diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/debug.py b/env/lib/python3.8/site-packages/pip/_internal/commands/debug.py deleted file mode 100644 index 665ffe96..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/debug.py +++ /dev/null @@ -1,258 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import locale -import logging -import os -import sys - -import pip._vendor -from pip._vendor import pkg_resources -from pip._vendor.certifi import where - -from pip import __file__ as pip_location -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import get_pip_version -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from types import ModuleType - from typing import Any, List, Optional, Dict - from optparse import Values - -logger = logging.getLogger(__name__) - - -def show_value(name, value): - # type: (str, Optional[str]) -> None - logger.info('{}: {}'.format(name, value)) - - -def show_sys_implementation(): - # type: () -> None - logger.info('sys.implementation:') - if hasattr(sys, 'implementation'): - implementation = sys.implementation # type: ignore - implementation_name = implementation.name - else: - implementation_name = '' - - with indent_log(): - show_value('name', implementation_name) - - -def create_vendor_txt_map(): - # type: () -> Dict[str, str] - vendor_txt_path = os.path.join( - os.path.dirname(pip_location), - '_vendor', - 'vendor.txt' - ) - - with open(vendor_txt_path) as f: - # Purge non version specifying lines. - # Also, remove any space prefix or suffixes (including comments). - lines = [line.strip().split(' ', 1)[0] - for line in f.readlines() if '==' in line] - - # Transform into "module" -> version dict. - return dict(line.split('==', 1) for line in lines) # type: ignore - -def create_debundle_txt_map(): - # type: () -> Dict[str, str] - wheels = [fn for fn in os.listdir(pip._vendor.WHEEL_DIR)] - # Transform into "module" -> version dict. - return dict((wheel.split('-')[0], wheel.split('-')[1]) for wheel in wheels) # type: ignore - -def get_module_from_module_name(module_name): - # type: (str) -> ModuleType - - # Module name can be uppercase in vendor.txt for some reason... - module_name = module_name.lower() - # PATCH: setuptools is actually only pkg_resources. - if module_name == 'setuptools': - module_name = 'pkg_resources' - - __import__( - 'pip._vendor.{}'.format(module_name), - globals(), - locals(), - level=0 - ) - return getattr(pip._vendor, module_name) - - -def get_vendor_version_from_module(module_name): - # type: (str) -> str - - module = get_module_from_module_name(module_name) - version = getattr(module, '__version__', None) - - if not version: - # Try to find version in debundled module info - pkg_set = pkg_resources.WorkingSet( - [os.path.dirname(getattr(module, '__file__'))] - ) - package = pkg_set.find(pkg_resources.Requirement.parse(module_name)) - version = getattr(package, 'version', None) - - return version - - -def show_actual_vendor_versions(vendor_txt_versions): - # type: (Dict[str, str]) -> None - # Logs the actual version and print extra info - # if there is a conflict or if the actual version could not be imported. - - for module_name, expected_version in vendor_txt_versions.items(): - extra_message = '' - actual_version = get_vendor_version_from_module(module_name) - if not actual_version: - extra_message = ' (Unable to locate actual module version, using'\ - ' vendor.txt specified version)' - actual_version = expected_version - elif actual_version != expected_version: - extra_message = ' (CONFLICT: vendor.txt suggests version should'\ - ' be {})'.format(expected_version) - - logger.info( - '{name}=={actual}{extra}'.format( - name=module_name, - actual=actual_version, - extra=extra_message - ) - ) - - -def show_vendor_versions(): - # type: () -> None - logger.info('vendored library versions:') - - vendor_txt_versions = create_vendor_txt_map() - with indent_log(): - show_actual_vendor_versions(vendor_txt_versions) - -def show_debundled_versions(): - # type: () -> None - logger.info('debundled wheel versions:') - debundle_txt_versions = create_debundle_txt_map() - for module_name, installed_version in sorted(debundle_txt_versions.items()): - with indent_log(): - logger.info( - '{name}=={actual}'.format( - name=module_name, - actual=installed_version, - ) - ) - -def show_tags(options): - # type: (Values) -> None - tag_limit = 10 - - target_python = make_target_python(options) - tags = target_python.get_tags() - - # Display the target options that were explicitly provided. - formatted_target = target_python.format_given() - suffix = '' - if formatted_target: - suffix = ' (target: {})'.format(formatted_target) - - msg = 'Compatible tags: {}{}'.format(len(tags), suffix) - logger.info(msg) - - if options.verbose < 1 and len(tags) > tag_limit: - tags_limited = True - tags = tags[:tag_limit] - else: - tags_limited = False - - with indent_log(): - for tag in tags: - logger.info(str(tag)) - - if tags_limited: - msg = ( - '...\n' - '[First {tag_limit} tags shown. Pass --verbose to show all.]' - ).format(tag_limit=tag_limit) - logger.info(msg) - - -def ca_bundle_info(config): - levels = set() - for key, value in config.items(): - levels.add(key.split('.')[0]) - - if not levels: - return "Not specified" - - levels_that_override_global = ['install', 'wheel', 'download'] - global_overriding_level = [ - level for level in levels if level in levels_that_override_global - ] - if not global_overriding_level: - return 'global' - - if 'global' in levels: - levels.remove('global') - return ", ".join(levels) - - -class DebugCommand(Command): - """ - Display debug information. - """ - - usage = """ - %prog """ - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(DebugCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - cmdoptions.add_target_python_options(cmd_opts) - self.parser.insert_option_group(0, cmd_opts) - self.parser.config.load() - - def run(self, options, args): - # type: (Values, List[Any]) -> int - logger.warning( - "This command is only meant for debugging. " - "Do not use this with automation for parsing and getting these " - "details, since the output and options of this command may " - "change without notice." - ) - show_value('pip version', get_pip_version()) - show_value('sys.version', sys.version) - show_value('sys.executable', sys.executable) - show_value('sys.getdefaultencoding', sys.getdefaultencoding()) - show_value('sys.getfilesystemencoding', sys.getfilesystemencoding()) - show_value( - 'locale.getpreferredencoding', locale.getpreferredencoding(), - ) - show_value('sys.platform', sys.platform) - show_sys_implementation() - - show_value("'cert' config value", ca_bundle_info(self.parser.config)) - show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE')) - show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE')) - show_value("pip._vendor.certifi.where()", where()) - show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED) - - if not pip._vendor.DEBUNDLED: - show_vendor_versions() - else: - show_value("pip._vendor.WHEEL_DIR", pip._vendor.WHEEL_DIR) - show_debundled_versions() - - show_tags(options) - - return SUCCESS diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/download.py b/env/lib/python3.8/site-packages/pip/_internal/commands/download.py deleted file mode 100644 index c8295506..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/download.py +++ /dev/null @@ -1,142 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os - -from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.req_command import RequirementCommand, with_cleanup -from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.misc import ensure_dir, normalize_path, write_output -from pip._internal.utils.temp_dir import TempDirectory - -logger = logging.getLogger(__name__) - - -class DownloadCommand(RequirementCommand): - """ - Download packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports downloading from "requirements files", which provide - an easy way to specify a whole environment to be downloaded. - """ - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] ... - %prog [options] ... - %prog [options] ...""" - - def __init__(self, *args, **kw): - super(DownloadCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.global_options()) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.pre()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option( - '-d', '--dest', '--destination-dir', '--destination-directory', - dest='download_dir', - metavar='dir', - default=os.curdir, - help=("Download packages into ."), - ) - - cmdoptions.add_target_python_options(cmd_opts) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - @with_cleanup - def run(self, options, args): - options.ignore_installed = True - # editable doesn't really make sense for `pip download`, but the bowels - # of the RequirementSet code require that property. - options.editables = [] - - cmdoptions.check_dist_restriction(options) - - options.download_dir = normalize_path(options.download_dir) - - ensure_dir(options.download_dir) - - session = self.get_default_session(options) - - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ) - build_delete = (not (options.no_clean or options.build_dir)) - - req_tracker = self.enter_context(get_requirement_tracker()) - - directory = TempDirectory( - options.build_dir, - delete=build_delete, - kind="download", - globally_managed=True, - ) - - reqs = self.get_requirements(args, options, finder, session) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - req_tracker=req_tracker, - session=session, - finder=finder, - download_dir=options.download_dir, - use_user_site=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - py_version_info=options.python_version, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve( - reqs, check_supported_wheels=True - ) - - downloaded = ' '.join([ - req.name for req in requirement_set.requirements.values() - if req.successfully_downloaded - ]) - if downloaded: - write_output('Successfully downloaded %s', downloaded) - - return requirement_set diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/freeze.py b/env/lib/python3.8/site-packages/pip/_internal/commands/freeze.py deleted file mode 100644 index 9e873a98..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/freeze.py +++ /dev/null @@ -1,99 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import sys - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.models.format_control import FormatControl -from pip._internal.operations.freeze import freeze -from pip._internal.utils.compat import stdlib_pkgs - -DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel', 'pkg-resources'} - - -class FreezeCommand(Command): - """ - Output installed packages in requirements format. - - packages are listed in a case-insensitive sorted order. - """ - - usage = """ - %prog [options]""" - log_streams = ("ext://sys.stderr", "ext://sys.stderr") - - def __init__(self, *args, **kw): - super(FreezeCommand, self).__init__(*args, **kw) - - self.cmd_opts.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help="Use the order in the given requirements file and its " - "comments when generating output. This option can be " - "used multiple times.") - self.cmd_opts.add_option( - '-f', '--find-links', - dest='find_links', - action='append', - default=[], - metavar='URL', - help='URL for finding packages, which will be added to the ' - 'output.') - self.cmd_opts.add_option( - '-l', '--local', - dest='local', - action='store_true', - default=False, - help='If in a virtualenv that has global access, do not output ' - 'globally-installed packages.') - self.cmd_opts.add_option( - '--user', - dest='user', - action='store_true', - default=False, - help='Only output packages installed in user-site.') - self.cmd_opts.add_option(cmdoptions.list_path()) - self.cmd_opts.add_option( - '--all', - dest='freeze_all', - action='store_true', - help='Do not skip these packages in the output:' - ' {}'.format(', '.join(DEV_PKGS))) - self.cmd_opts.add_option( - '--exclude-editable', - dest='exclude_editable', - action='store_true', - help='Exclude editable package from output.') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - format_control = FormatControl(set(), set()) - wheel_cache = WheelCache(options.cache_dir, format_control) - skip = set(stdlib_pkgs) - if not options.freeze_all: - skip.update(DEV_PKGS) - - cmdoptions.check_list_path_option(options) - - freeze_kwargs = dict( - requirement=options.requirements, - find_links=options.find_links, - local_only=options.local, - user_only=options.user, - paths=options.path, - isolated=options.isolated_mode, - wheel_cache=wheel_cache, - skip=skip, - exclude_editable=options.exclude_editable, - ) - - for line in freeze(**freeze_kwargs): - sys.stdout.write(line + '\n') diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/hash.py b/env/lib/python3.8/site-packages/pip/_internal/commands/hash.py deleted file mode 100644 index f2668615..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/hash.py +++ /dev/null @@ -1,58 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import hashlib -import logging -import sys - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR -from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES -from pip._internal.utils.misc import read_chunks, write_output - -logger = logging.getLogger(__name__) - - -class HashCommand(Command): - """ - Compute a hash of a local package archive. - - These can be used with --hash in a requirements file to do repeatable - installs. - """ - - usage = '%prog [options] ...' - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(HashCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-a', '--algorithm', - dest='algorithm', - choices=STRONG_HASHES, - action='store', - default=FAVORITE_HASH, - help='The hash algorithm to use: one of {}'.format( - ', '.join(STRONG_HASHES))) - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - self.parser.print_usage(sys.stderr) - return ERROR - - algorithm = options.algorithm - for path in args: - write_output('%s:\n--hash=%s:%s', - path, algorithm, _hash_of_file(path, algorithm)) - - -def _hash_of_file(path, algorithm): - """Return the hash digest of a file.""" - with open(path, 'rb') as archive: - hash = hashlib.new(algorithm) - for chunk in read_chunks(archive): - hash.update(chunk) - return hash.hexdigest() diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/help.py b/env/lib/python3.8/site-packages/pip/_internal/commands/help.py deleted file mode 100644 index c17d7a45..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/help.py +++ /dev/null @@ -1,41 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError - - -class HelpCommand(Command): - """Show help for commands""" - - usage = """ - %prog """ - ignore_require_venv = True - - def run(self, options, args): - from pip._internal.commands import ( - commands_dict, create_command, get_similar_commands, - ) - - try: - # 'pip help' with no args is handled by pip.__init__.parseopt() - cmd_name = args[0] # the command we need help for - except IndexError: - return SUCCESS - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = ['unknown command "{}"'.format(cmd_name)] - if guess: - msg.append('maybe you meant "{}"'.format(guess)) - - raise CommandError(' - '.join(msg)) - - command = create_command(cmd_name) - command.parser.print_help() - - return SUCCESS diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/install.py b/env/lib/python3.8/site-packages/pip/_internal/commands/install.py deleted file mode 100644 index b40f045c..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/install.py +++ /dev/null @@ -1,717 +0,0 @@ -# The following comment should be removed at some point in the future. -# It's included for now because without it InstallCommand.run() has a -# couple errors where we have to know req.name is str rather than -# Optional[str] for the InstallRequirement req. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import errno -import logging -import operator -import os -import shutil -import site -from optparse import SUPPRESS_HELP - -from pip._vendor import pkg_resources -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.req_command import RequirementCommand, with_cleanup -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.exceptions import CommandError, InstallationError -from pip._internal.locations import distutils_scheme -from pip._internal.operations.check import check_install_conflicts -from pip._internal.req import install_given_reqs -from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.distutils_args import parse_distutils_args -from pip._internal.utils.filesystem import test_writable_dir -from pip._internal.utils.misc import ( - ensure_dir, - get_installed_version, - protect_pip_from_modification_on_windows, - write_output, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.virtualenv import virtualenv_no_global -from pip._internal.wheel_builder import build, should_build_for_install_command - -if MYPY_CHECK_RUNNING: - from optparse import Values - from typing import Any, Iterable, List, Optional - - from pip._internal.models.format_control import FormatControl - from pip._internal.req.req_install import InstallRequirement - from pip._internal.wheel_builder import BinaryAllowedPredicate - -from pip._internal.locations import running_under_virtualenv - -logger = logging.getLogger(__name__) - - -def get_check_binary_allowed(format_control): - # type: (FormatControl) -> BinaryAllowedPredicate - def check_binary_allowed(req): - # type: (InstallRequirement) -> bool - if req.use_pep517: - return True - canonical_name = canonicalize_name(req.name) - allowed_formats = format_control.get_allowed_formats(canonical_name) - return "binary" in allowed_formats - - return check_binary_allowed - - -class InstallCommand(RequirementCommand): - """ - Install packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports installing from "requirements files", which provide - an easy way to specify a whole environment to be installed. - """ - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - def __init__(self, *args, **kw): - super(InstallCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.pre()) - - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option( - '-t', '--target', - dest='target_dir', - metavar='dir', - default=None, - help='Install packages into . ' - 'By default this will not replace existing files/folders in ' - '. Use --upgrade to replace existing packages in ' - 'with new versions.' - ) - cmdoptions.add_target_python_options(cmd_opts) - - cmd_opts.add_option( - '--user', - dest='use_user_site', - action='store_true', - help="Install to the Python user install directory for your " - "platform. Typically ~/.local/, or %APPDATA%\\Python on " - "Windows. (See the Python documentation for site.USER_BASE " - "for full details.) On Debian systems, this is the " - "default when running outside of a virtual environment " - "and not as root.") - - cmd_opts.add_option( - '--no-user', - dest='use_system_location', - action='store_true', - help=SUPPRESS_HELP) - cmd_opts.add_option( - '--root', - dest='root_path', - metavar='dir', - default=None, - help="Install everything relative to this alternate root " - "directory.") - cmd_opts.add_option( - '--prefix', - dest='prefix_path', - metavar='dir', - default=None, - help="Installation prefix where lib, bin and other top-level " - "folders are placed") - - cmd_opts.add_option( - '--system', - dest='use_system_location', - action='store_true', - help="Install using the system scheme (overrides --user on " - "Debian systems)") - - cmd_opts.add_option(cmdoptions.build_dir()) - - cmd_opts.add_option(cmdoptions.src()) - - cmd_opts.add_option( - '-U', '--upgrade', - dest='upgrade', - action='store_true', - help='Upgrade all specified packages to the newest available ' - 'version. The handling of dependencies depends on the ' - 'upgrade-strategy used.' - ) - - cmd_opts.add_option( - '--upgrade-strategy', - dest='upgrade_strategy', - default='only-if-needed', - choices=['only-if-needed', 'eager'], - help='Determines how dependency upgrading should be handled ' - '[default: %default]. ' - '"eager" - dependencies are upgraded regardless of ' - 'whether the currently installed version satisfies the ' - 'requirements of the upgraded package(s). ' - '"only-if-needed" - are upgraded only when they do not ' - 'satisfy the requirements of the upgraded package(s).' - ) - - cmd_opts.add_option( - '--force-reinstall', - dest='force_reinstall', - action='store_true', - help='Reinstall all packages even if they are already ' - 'up-to-date.') - - cmd_opts.add_option( - '-I', '--ignore-installed', - dest='ignore_installed', - action='store_true', - help='Ignore the installed packages, overwriting them. ' - 'This can break your system if the existing package ' - 'is of a different version or was installed ' - 'with a different package manager!' - ) - - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option(cmdoptions.install_options()) - cmd_opts.add_option(cmdoptions.global_options()) - - cmd_opts.add_option( - "--compile", - action="store_true", - dest="compile", - default=True, - help="Compile Python source files to bytecode", - ) - - cmd_opts.add_option( - "--no-compile", - action="store_false", - dest="compile", - help="Do not compile Python source files to bytecode", - ) - - cmd_opts.add_option( - "--no-warn-script-location", - action="store_false", - dest="warn_script_location", - default=True, - help="Do not warn when installing scripts outside PATH", - ) - cmd_opts.add_option( - "--no-warn-conflicts", - action="store_false", - dest="warn_about_conflicts", - default=True, - help="Do not warn about broken dependencies", - ) - - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - @with_cleanup - def run(self, options, args): - # type: (Values, List[Any]) -> int - if options.use_user_site and options.target_dir is not None: - raise CommandError("Can not combine '--user' and '--target'") - - cmdoptions.check_install_build_global(options) - upgrade_strategy = "to-satisfy-only" - if options.upgrade: - upgrade_strategy = options.upgrade_strategy - - cmdoptions.check_dist_restriction(options, check_target=True) - - if options.python_version: - python_versions = [options.python_version] - else: - python_versions = None - - # compute install location defaults - if (not options.use_user_site and not options.prefix_path and not - options.target_dir and not options.use_system_location): - if not running_under_virtualenv() and os.geteuid() != 0: - options.use_user_site = True - - if options.use_system_location: - options.use_user_site = False - - options.src_dir = os.path.abspath(options.src_dir) - install_options = options.install_options or [] - - options.use_user_site = decide_user_install( - options.use_user_site, - prefix_path=options.prefix_path, - target_dir=options.target_dir, - root_path=options.root_path, - isolated_mode=options.isolated_mode, - ) - - target_temp_dir = None # type: Optional[TempDirectory] - target_temp_dir_path = None # type: Optional[str] - if options.target_dir: - options.ignore_installed = True - options.target_dir = os.path.abspath(options.target_dir) - if (os.path.exists(options.target_dir) and not - os.path.isdir(options.target_dir)): - raise CommandError( - "Target path exists but is not a directory, will not " - "continue." - ) - - # Create a target directory for using with the target option - target_temp_dir = TempDirectory(kind="target") - target_temp_dir_path = target_temp_dir.path - - global_options = options.global_options or [] - - session = self.get_default_session(options) - - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ignore_requires_python=options.ignore_requires_python, - ) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - - req_tracker = self.enter_context(get_requirement_tracker()) - - directory = TempDirectory( - options.build_dir, - delete=build_delete, - kind="install", - globally_managed=True, - ) - - try: - reqs = self.get_requirements( - args, options, finder, session, - check_supported_wheels=not options.target_dir, - ) - - warn_deprecated_install_options( - reqs, options.install_options - ) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - req_tracker=req_tracker, - session=session, - finder=finder, - use_user_site=options.use_user_site, - ) - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - use_user_site=options.use_user_site, - ignore_installed=options.ignore_installed, - ignore_requires_python=options.ignore_requires_python, - force_reinstall=options.force_reinstall, - upgrade_strategy=upgrade_strategy, - use_pep517=options.use_pep517, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve( - reqs, check_supported_wheels=not options.target_dir - ) - - try: - pip_req = requirement_set.get_requirement("pip") - except KeyError: - modifying_pip = None - else: - # If we're not replacing an already installed pip, - # we're not modifying it. - modifying_pip = pip_req.satisfied_by is None - protect_pip_from_modification_on_windows( - modifying_pip=modifying_pip - ) - - check_binary_allowed = get_check_binary_allowed( - finder.format_control - ) - - reqs_to_build = [ - r for r in requirement_set.requirements.values() - if should_build_for_install_command( - r, check_binary_allowed - ) - ] - - _, build_failures = build( - reqs_to_build, - wheel_cache=wheel_cache, - build_options=[], - global_options=[], - ) - - # If we're using PEP 517, we cannot do a direct install - # so we fail here. - # We don't care about failures building legacy - # requirements, as we'll fall through to a direct - # install for those. - pep517_build_failures = [ - r for r in build_failures if r.use_pep517 - ] - if pep517_build_failures: - raise InstallationError( - "Could not build wheels for {} which use" - " PEP 517 and cannot be installed directly".format( - ", ".join(r.name for r in pep517_build_failures))) - - to_install = resolver.get_installation_order( - requirement_set - ) - - # Consistency Checking of the package set we're installing. - should_warn_about_conflicts = ( - not options.ignore_dependencies and - options.warn_about_conflicts - ) - if should_warn_about_conflicts: - self._warn_about_conflicts(to_install) - - # Don't warn about script install locations if - # --target has been specified - warn_script_location = options.warn_script_location - if options.target_dir: - warn_script_location = False - - installed = install_given_reqs( - to_install, - install_options, - global_options, - root=options.root_path, - home=target_temp_dir_path, - prefix=options.prefix_path, - pycompile=options.compile, - warn_script_location=warn_script_location, - use_user_site=options.use_user_site, - ) - - lib_locations = get_lib_location_guesses( - user=options.use_user_site, - home=target_temp_dir_path, - root=options.root_path, - prefix=options.prefix_path, - isolated=options.isolated_mode, - ) - working_set = pkg_resources.WorkingSet(lib_locations) - - installed.sort(key=operator.attrgetter('name')) - items = [] - for result in installed: - item = result.name - try: - installed_version = get_installed_version( - result.name, working_set=working_set - ) - if installed_version: - item += '-' + installed_version - except Exception: - pass - items.append(item) - installed_desc = ' '.join(items) - if installed_desc: - write_output( - 'Successfully installed %s', installed_desc, - ) - except EnvironmentError as error: - show_traceback = (self.verbosity >= 1) - - message = create_env_error_message( - error, show_traceback, options.use_user_site, - ) - logger.error(message, exc_info=show_traceback) - - return ERROR - - if options.target_dir: - self._handle_target_dir( - options.target_dir, target_temp_dir, options.upgrade - ) - - return SUCCESS - - def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): - ensure_dir(target_dir) - - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - lib_dir_list = [] - - with target_temp_dir: - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - scheme = distutils_scheme('', home=target_temp_dir.path) - purelib_dir = scheme['purelib'] - platlib_dir = scheme['platlib'] - data_dir = scheme['data'] - - if os.path.exists(purelib_dir): - lib_dir_list.append(purelib_dir) - if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: - lib_dir_list.append(platlib_dir) - if os.path.exists(data_dir): - lib_dir_list.append(data_dir) - - for lib_dir in lib_dir_list: - for item in os.listdir(lib_dir): - if lib_dir == data_dir: - ddir = os.path.join(data_dir, item) - if any(s.startswith(ddir) for s in lib_dir_list[:-1]): - continue - target_item_dir = os.path.join(target_dir, item) - if os.path.exists(target_item_dir): - if not upgrade: - logger.warning( - 'Target directory %s already exists. Specify ' - '--upgrade to force replacement.', - target_item_dir - ) - continue - if os.path.islink(target_item_dir): - logger.warning( - 'Target directory %s already exists and is ' - 'a link. pip will not automatically replace ' - 'links, please remove if replacement is ' - 'desired.', - target_item_dir - ) - continue - if os.path.isdir(target_item_dir): - shutil.rmtree(target_item_dir) - else: - os.remove(target_item_dir) - - shutil.move( - os.path.join(lib_dir, item), - target_item_dir - ) - - def _warn_about_conflicts(self, to_install): - try: - package_set, _dep_info = check_install_conflicts(to_install) - except Exception: - logger.error("Error checking for conflicts.", exc_info=True) - return - missing, conflicting = _dep_info - - # NOTE: There is some duplication here from pip check - for project_name in missing: - version = package_set[project_name][0] - for dependency in missing[project_name]: - logger.critical( - "%s %s requires %s, which is not installed.", - project_name, version, dependency[1], - ) - - for project_name in conflicting: - version = package_set[project_name][0] - for dep_name, dep_version, req in conflicting[project_name]: - logger.critical( - "%s %s has requirement %s, but you'll have %s %s which is " - "incompatible.", - project_name, version, req, dep_name, dep_version, - ) - - -def get_lib_location_guesses(*args, **kwargs): - scheme = distutils_scheme('', *args, **kwargs) - return [scheme['purelib'], scheme['platlib']] - - -def site_packages_writable(**kwargs): - return all( - test_writable_dir(d) for d in set(get_lib_location_guesses(**kwargs)) - ) - - -def decide_user_install( - use_user_site, # type: Optional[bool] - prefix_path=None, # type: Optional[str] - target_dir=None, # type: Optional[str] - root_path=None, # type: Optional[str] - isolated_mode=False, # type: bool -): - # type: (...) -> bool - """Determine whether to do a user install based on the input options. - - If use_user_site is False, no additional checks are done. - If use_user_site is True, it is checked for compatibility with other - options. - If use_user_site is None, the default behaviour depends on the environment, - which is provided by the other arguments. - """ - # In some cases (config from tox), use_user_site can be set to an integer - # rather than a bool, which 'use_user_site is False' wouldn't catch. - if (use_user_site is not None) and (not use_user_site): - logger.debug("Non-user install by explicit request") - return False - - if use_user_site: - if prefix_path: - raise CommandError( - "Can not combine '--user' and '--prefix' as they imply " - "different installation locations" - ) - if virtualenv_no_global(): - raise InstallationError( - "Can not perform a '--user' install. User site-packages " - "are not visible in this virtualenv." - ) - logger.debug("User install by explicit request") - return True - - # If we are here, user installs have not been explicitly requested/avoided - assert use_user_site is None - - # user install incompatible with --prefix/--target - if prefix_path or target_dir: - logger.debug("Non-user install due to --prefix or --target option") - return False - - # If user installs are not enabled, choose a non-user install - if not site.ENABLE_USER_SITE: - logger.debug("Non-user install because user site-packages disabled") - return False - - # If we have permission for a non-user install, do that, - # otherwise do a user install. - if site_packages_writable(root=root_path, isolated=isolated_mode): - logger.debug("Non-user install because site-packages writeable") - return False - - logger.info("Defaulting to user installation because normal site-packages " - "is not writeable") - return True - - -def warn_deprecated_install_options(requirements, options): - # type: (List[InstallRequirement], Optional[List[str]]) -> None - """If any location-changing --install-option arguments were passed for - requirements or on the command-line, then show a deprecation warning. - """ - def format_options(option_names): - # type: (Iterable[str]) -> List[str] - return ["--{}".format(name.replace("_", "-")) for name in option_names] - - offenders = [] - - for requirement in requirements: - install_options = requirement.install_options - location_options = parse_distutils_args(install_options) - if location_options: - offenders.append( - "{!r} from {}".format( - format_options(location_options.keys()), requirement - ) - ) - - if options: - location_options = parse_distutils_args(options) - if location_options: - offenders.append( - "{!r} from command line".format( - format_options(location_options.keys()) - ) - ) - - if not offenders: - return - - deprecated( - reason=( - "Location-changing options found in --install-option: {}. " - "This configuration may cause unexpected behavior and is " - "unsupported.".format( - "; ".join(offenders) - ) - ), - replacement=( - "using pip-level options like --user, --prefix, --root, and " - "--target" - ), - gone_in="20.2", - issue=7309, - ) - - -def create_env_error_message(error, show_traceback, using_user_site): - """Format an error message for an EnvironmentError - - It may occur anytime during the execution of the install command. - """ - parts = [] - - # Mention the error if we are not going to show a traceback - parts.append("Could not install packages due to an EnvironmentError") - if not show_traceback: - parts.append(": ") - parts.append(str(error)) - else: - parts.append(".") - - # Spilt the error indication from a helper message (if any) - parts[-1] += "\n" - - # Suggest useful actions to the user: - # (1) using user site-packages or (2) verifying the permissions - if error.errno == errno.EACCES: - user_option_part = "Consider using the `--user` option" - permissions_part = "Check the permissions" - - if not using_user_site: - parts.extend([ - user_option_part, " or ", - permissions_part.lower(), - ]) - else: - parts.append(permissions_part) - parts.append(".\n") - - return "".join(parts).strip() + "\n" diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/list.py b/env/lib/python3.8/site-packages/pip/_internal/commands/list.py deleted file mode 100644 index 13715ce1..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/list.py +++ /dev/null @@ -1,301 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import json -import logging - -from pip._vendor import six - -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import IndexGroupCommand -from pip._internal.exceptions import CommandError -from pip._internal.index.package_finder import PackageFinder -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.self_outdated_check import make_link_collector -from pip._internal.utils.misc import ( - dist_is_editable, - get_installed_distributions, - tabulate, - write_output, -) -from pip._internal.utils.packaging import get_installer - -from pip._vendor.packaging.version import parse - -logger = logging.getLogger(__name__) - - -class ListCommand(IndexGroupCommand): - """ - List installed packages, including editables. - - Packages are listed in a case-insensitive sorted order. - """ - - usage = """ - %prog [options]""" - - def __init__(self, *args, **kw): - super(ListCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '-o', '--outdated', - action='store_true', - default=False, - help='List outdated packages') - cmd_opts.add_option( - '-u', '--uptodate', - action='store_true', - default=False, - help='List uptodate packages') - cmd_opts.add_option( - '-e', '--editable', - action='store_true', - default=False, - help='List editable projects.') - cmd_opts.add_option( - '-l', '--local', - action='store_true', - default=False, - help=('If in a virtualenv that has global access, do not list ' - 'globally-installed packages.'), - ) - self.cmd_opts.add_option( - '--user', - dest='user', - action='store_true', - default=False, - help='Only output packages installed in user-site.') - cmd_opts.add_option(cmdoptions.list_path()) - cmd_opts.add_option( - '--pre', - action='store_true', - default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), - ) - - cmd_opts.add_option( - '--format', - action='store', - dest='list_format', - default="columns", - choices=('columns', 'freeze', 'json'), - help="Select the output format among: columns (default), freeze, " - "or json", - ) - - cmd_opts.add_option( - '--not-required', - action='store_true', - dest='not_required', - help="List packages that are not dependencies of " - "installed packages.", - ) - - cmd_opts.add_option( - '--exclude-editable', - action='store_false', - dest='include_editable', - help='Exclude editable package from output.', - ) - cmd_opts.add_option( - '--include-editable', - action='store_true', - dest='include_editable', - help='Include editable package from output.', - default=True, - ) - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, self.parser - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def _build_package_finder(self, options, session): - """ - Create a package finder appropriate to this list command. - """ - link_collector = make_link_collector(session, options=options) - - # Pass allow_yanked=False to ignore yanked versions. - selection_prefs = SelectionPreferences( - allow_yanked=False, - allow_all_prereleases=options.pre, - ) - - return PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - ) - - def run(self, options, args): - if options.outdated and options.uptodate: - raise CommandError( - "Options --outdated and --uptodate cannot be combined.") - - cmdoptions.check_list_path_option(options) - - packages = get_installed_distributions( - local_only=options.local, - user_only=options.user, - editables_only=options.editable, - include_editables=options.include_editable, - paths=options.path, - ) - - # get_not_required must be called firstly in order to find and - # filter out all dependencies correctly. Otherwise a package - # can't be identified as requirement because some parent packages - # could be filtered out before. - if options.not_required: - packages = self.get_not_required(packages, options) - - if options.outdated: - packages = self.get_outdated(packages, options) - elif options.uptodate: - packages = self.get_uptodate(packages, options) - - self.output_package_listing(packages, options) - - def get_outdated(self, packages, options): - return [ - dist for dist in self.iter_packages_latest_infos(packages, options) - if parse(str(dist.latest_version)) > parse(str(dist.parsed_version)) - ] - - def get_uptodate(self, packages, options): - return [ - dist for dist in self.iter_packages_latest_infos(packages, options) - if parse(str(dist.latest_version)) == parse(str(dist.parsed_version)) - ] - - def get_not_required(self, packages, options): - dep_keys = set() - for dist in packages: - dep_keys.update(requirement.key for requirement in dist.requires()) - return {pkg for pkg in packages if pkg.key not in dep_keys} - - def iter_packages_latest_infos(self, packages, options): - with self._build_session(options) as session: - finder = self._build_package_finder(options, session) - - def latest_info(dist): - typ = 'unknown' - all_candidates = finder.find_all_candidates(dist.key) - if not options.pre: - # Remove prereleases - all_candidates = [candidate for candidate in all_candidates - if not candidate.version.is_prerelease] - - evaluator = finder.make_candidate_evaluator( - project_name=dist.project_name, - ) - best_candidate = evaluator.sort_best_candidate(all_candidates) - if best_candidate is None: - return None - - remote_version = best_candidate.version - if best_candidate.link.is_wheel: - typ = 'wheel' - else: - typ = 'sdist' - # This is dirty but makes the rest of the code much cleaner - dist.latest_version = remote_version - dist.latest_filetype = typ - return dist - - for dist in map(latest_info, packages): - if dist is not None: - yield dist - - def output_package_listing(self, packages, options): - packages = sorted( - packages, - key=lambda dist: dist.project_name.lower(), - ) - if options.list_format == 'columns' and packages: - data, header = format_for_columns(packages, options) - self.output_package_listing_columns(data, header) - elif options.list_format == 'freeze': - for dist in packages: - if options.verbose >= 1: - write_output("%s==%s (%s)", dist.project_name, - dist.version, dist.location) - else: - write_output("%s==%s", dist.project_name, dist.version) - elif options.list_format == 'json': - write_output(format_for_json(packages, options)) - - def output_package_listing_columns(self, data, header): - # insert the header first: we need to know the size of column names - if len(data) > 0: - data.insert(0, header) - - pkg_strings, sizes = tabulate(data) - - # Create and add a separator. - if len(data) > 0: - pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) - - for val in pkg_strings: - write_output(val) - - -def format_for_columns(pkgs, options): - """ - Convert the package data into something usable - by output_package_listing_columns. - """ - running_outdated = options.outdated - # Adjust the header for the `pip list --outdated` case. - if running_outdated: - header = ["Package", "Version", "Latest", "Type"] - else: - header = ["Package", "Version"] - - data = [] - if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): - header.append("Location") - if options.verbose >= 1: - header.append("Installer") - - for proj in pkgs: - # if we're working on the 'outdated' list, separate out the - # latest_version and type - row = [proj.project_name, proj.version] - - if running_outdated: - row.append(proj.latest_version) - row.append(proj.latest_filetype) - - if options.verbose >= 1 or dist_is_editable(proj): - row.append(proj.location) - if options.verbose >= 1: - row.append(get_installer(proj)) - - data.append(row) - - return data, header - - -def format_for_json(packages, options): - data = [] - for dist in packages: - info = { - 'name': dist.project_name, - 'version': six.text_type(dist.version), - } - if options.verbose >= 1: - info['location'] = dist.location - info['installer'] = get_installer(dist) - if options.outdated: - info['latest_version'] = six.text_type(dist.latest_version) - info['latest_filetype'] = dist.latest_filetype - data.append(info) - return json.dumps(data) diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/search.py b/env/lib/python3.8/site-packages/pip/_internal/commands/search.py deleted file mode 100644 index e5f286ea..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/search.py +++ /dev/null @@ -1,146 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import sys -import textwrap -from collections import OrderedDict - -from pip._vendor import pkg_resources -from pip._vendor.packaging.version import parse as parse_version -# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import -from pip._vendor.six.moves import xmlrpc_client # type: ignore - -from pip._internal.cli.base_command import Command -from pip._internal.cli.req_command import SessionCommandMixin -from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS -from pip._internal.exceptions import CommandError -from pip._internal.models.index import PyPI -from pip._internal.network.xmlrpc import PipXmlrpcTransport -from pip._internal.utils.compat import get_terminal_size -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import write_output - -logger = logging.getLogger(__name__) - - -class SearchCommand(Command, SessionCommandMixin): - """Search for PyPI packages whose name or summary contains .""" - - usage = """ - %prog [options] """ - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(SearchCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-i', '--index', - dest='index', - metavar='URL', - default=PyPI.pypi_url, - help='Base URL of Python Package Index (default %default)') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - raise CommandError('Missing required argument (search query).') - query = args - pypi_hits = self.search(query, options) - hits = transform_hits(pypi_hits) - - terminal_width = None - if sys.stdout.isatty(): - terminal_width = get_terminal_size()[0] - - print_results(hits, terminal_width=terminal_width) - if pypi_hits: - return SUCCESS - return NO_MATCHES_FOUND - - def search(self, query, options): - index_url = options.index - - session = self.get_default_session(options) - - transport = PipXmlrpcTransport(index_url, session) - pypi = xmlrpc_client.ServerProxy(index_url, transport) - hits = pypi.search({'name': query, 'summary': query}, 'or') - return hits - - -def transform_hits(hits): - """ - The list from pypi is really a list of versions. We want a list of - packages with the list of versions stored inline. This converts the - list from pypi into one we can use. - """ - packages = OrderedDict() - for hit in hits: - name = hit['name'] - summary = hit['summary'] - version = hit['version'] - - if name not in packages.keys(): - packages[name] = { - 'name': name, - 'summary': summary, - 'versions': [version], - } - else: - packages[name]['versions'].append(version) - - # if this is the highest version, replace summary and score - if version == highest_version(packages[name]['versions']): - packages[name]['summary'] = summary - - return list(packages.values()) - - -def print_results(hits, name_column_width=None, terminal_width=None): - if not hits: - return - if name_column_width is None: - name_column_width = max([ - len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) - for hit in hits - ]) + 4 - - installed_packages = [p.project_name for p in pkg_resources.working_set] - for hit in hits: - name = hit['name'] - summary = hit['summary'] or '' - latest = highest_version(hit.get('versions', ['-'])) - if terminal_width is not None: - target_width = terminal_width - name_column_width - 5 - if target_width > 10: - # wrap and indent summary to fit terminal - summary = textwrap.wrap(summary, target_width) - summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) - - line = '{name_latest:{name_column_width}} - {summary}'.format( - name_latest='{name} ({latest})'.format(**locals()), - **locals()) - try: - write_output(line) - if name in installed_packages: - dist = pkg_resources.get_distribution(name) - with indent_log(): - if dist.version == latest: - write_output('INSTALLED: %s (latest)', dist.version) - else: - write_output('INSTALLED: %s', dist.version) - if parse_version(latest).pre: - write_output('LATEST: %s (pre-release; install' - ' with "pip install --pre")', latest) - else: - write_output('LATEST: %s', latest) - except UnicodeEncodeError: - pass - - -def highest_version(versions): - return max(versions, key=parse_version) diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/show.py b/env/lib/python3.8/site-packages/pip/_internal/commands/show.py deleted file mode 100644 index a61294ba..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/show.py +++ /dev/null @@ -1,180 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os -from email.parser import FeedParser - -from pip._vendor import pkg_resources -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.utils.misc import write_output - -logger = logging.getLogger(__name__) - - -class ShowCommand(Command): - """ - Show information about one or more installed packages. - - The output is in RFC-compliant mail header format. - """ - - usage = """ - %prog [options] ...""" - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(ShowCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-f', '--files', - dest='files', - action='store_true', - default=False, - help='Show the full list of installed files for each package.') - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - if not args: - logger.warning('ERROR: Please provide a package name or names.') - return ERROR - query = args - - results = search_packages_info(query) - if not print_results( - results, list_files=options.files, verbose=options.verbose): - return ERROR - return SUCCESS - - -def search_packages_info(query): - """ - Gather details from installed distributions. Print distribution name, - version, location, and installed files. Installed files requires a - pip generated 'installed-files.txt' in the distributions '.egg-info' - directory. - """ - installed = {} - for p in pkg_resources.working_set: - installed[canonicalize_name(p.project_name)] = p - - query_names = [canonicalize_name(name) for name in query] - missing = sorted( - [name for name, pkg in zip(query, query_names) if pkg not in installed] - ) - if missing: - logger.warning('Package(s) not found: %s', ', '.join(missing)) - - def get_requiring_packages(package_name): - canonical_name = canonicalize_name(package_name) - return [ - pkg.project_name for pkg in pkg_resources.working_set - if canonical_name in - [canonicalize_name(required.name) for required in - pkg.requires()] - ] - - for dist in [installed[pkg] for pkg in query_names if pkg in installed]: - package = { - 'name': dist.project_name, - 'version': dist.version, - 'location': dist.location, - 'requires': [dep.project_name for dep in dist.requires()], - 'required_by': get_requiring_packages(dist.project_name) - } - file_list = None - metadata = None - if isinstance(dist, pkg_resources.DistInfoDistribution): - # RECORDs should be part of .dist-info metadatas - if dist.has_metadata('RECORD'): - lines = dist.get_metadata_lines('RECORD') - paths = [l.split(',')[0] for l in lines] - paths = [os.path.join(dist.location, p) for p in paths] - file_list = [os.path.relpath(p, dist.location) for p in paths] - - if dist.has_metadata('METADATA'): - metadata = dist.get_metadata('METADATA') - else: - # Otherwise use pip's log for .egg-info's - if dist.has_metadata('installed-files.txt'): - paths = dist.get_metadata_lines('installed-files.txt') - paths = [os.path.join(dist.egg_info, p) for p in paths] - file_list = [os.path.relpath(p, dist.location) for p in paths] - - if dist.has_metadata('PKG-INFO'): - metadata = dist.get_metadata('PKG-INFO') - - if dist.has_metadata('entry_points.txt'): - entry_points = dist.get_metadata_lines('entry_points.txt') - package['entry_points'] = entry_points - - if dist.has_metadata('INSTALLER'): - for line in dist.get_metadata_lines('INSTALLER'): - if line.strip(): - package['installer'] = line.strip() - break - - # @todo: Should pkg_resources.Distribution have a - # `get_pkg_info` method? - feed_parser = FeedParser() - feed_parser.feed(metadata) - pkg_info_dict = feed_parser.close() - for key in ('metadata-version', 'summary', - 'home-page', 'author', 'author-email', 'license'): - package[key] = pkg_info_dict.get(key) - - # It looks like FeedParser cannot deal with repeated headers - classifiers = [] - for line in metadata.splitlines(): - if line.startswith('Classifier: '): - classifiers.append(line[len('Classifier: '):]) - package['classifiers'] = classifiers - - if file_list: - package['files'] = sorted(file_list) - yield package - - -def print_results(distributions, list_files=False, verbose=False): - """ - Print the information from installed distributions found. - """ - results_printed = False - for i, dist in enumerate(distributions): - results_printed = True - if i > 0: - write_output("---") - - write_output("Name: %s", dist.get('name', '')) - write_output("Version: %s", dist.get('version', '')) - write_output("Summary: %s", dist.get('summary', '')) - write_output("Home-page: %s", dist.get('home-page', '')) - write_output("Author: %s", dist.get('author', '')) - write_output("Author-email: %s", dist.get('author-email', '')) - write_output("License: %s", dist.get('license', '')) - write_output("Location: %s", dist.get('location', '')) - write_output("Requires: %s", ', '.join(dist.get('requires', []))) - write_output("Required-by: %s", ', '.join(dist.get('required_by', []))) - - if verbose: - write_output("Metadata-Version: %s", - dist.get('metadata-version', '')) - write_output("Installer: %s", dist.get('installer', '')) - write_output("Classifiers:") - for classifier in dist.get('classifiers', []): - write_output(" %s", classifier) - write_output("Entry-points:") - for entry in dist.get('entry_points', []): - write_output(" %s", entry.strip()) - if list_files: - write_output("Files:") - for line in dist.get('files', []): - write_output(" %s", line.strip()) - if "files" not in dist: - write_output("Cannot locate installed-files.txt") - return results_printed diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py b/env/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py deleted file mode 100644 index 5db4fb46..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py +++ /dev/null @@ -1,89 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.cli.base_command import Command -from pip._internal.cli.req_command import SessionCommandMixin -from pip._internal.exceptions import InstallationError -from pip._internal.req import parse_requirements -from pip._internal.req.constructors import ( - install_req_from_line, - install_req_from_parsed_requirement, -) -from pip._internal.utils.misc import protect_pip_from_modification_on_windows - - -class UninstallCommand(Command, SessionCommandMixin): - """ - Uninstall packages. - - pip is able to uninstall most installed packages. Known exceptions are: - - - Pure distutils packages installed with ``python setup.py install``, which - leave behind no metadata to determine what files were installed. - - Script wrappers installed by ``python setup.py develop``. - """ - - usage = """ - %prog [options] ... - %prog [options] -r ...""" - - def __init__(self, *args, **kw): - super(UninstallCommand, self).__init__(*args, **kw) - self.cmd_opts.add_option( - '-r', '--requirement', - dest='requirements', - action='append', - default=[], - metavar='file', - help='Uninstall all the packages listed in the given requirements ' - 'file. This option can be used multiple times.', - ) - self.cmd_opts.add_option( - '-y', '--yes', - dest='yes', - action='store_true', - help="Don't ask for confirmation of uninstall deletions.") - - self.parser.insert_option_group(0, self.cmd_opts) - - def run(self, options, args): - session = self.get_default_session(options) - - reqs_to_uninstall = {} - for name in args: - req = install_req_from_line( - name, isolated=options.isolated_mode, - ) - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - for filename in options.requirements: - for parsed_req in parse_requirements( - filename, - options=options, - session=session): - req = install_req_from_parsed_requirement( - parsed_req, - isolated=options.isolated_mode - ) - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - if not reqs_to_uninstall: - raise InstallationError( - 'You must give at least one requirement to {self.name} (see ' - '"pip help {self.name}")'.format(**locals()) - ) - - protect_pip_from_modification_on_windows( - modifying_pip="pip" in reqs_to_uninstall - ) - - for req in reqs_to_uninstall.values(): - uninstall_pathset = req.uninstall( - auto_confirm=options.yes, verbose=self.verbosity > 0, - ) - if uninstall_pathset: - uninstall_pathset.commit() diff --git a/env/lib/python3.8/site-packages/pip/_internal/commands/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/commands/wheel.py deleted file mode 100644 index 48f3bfa2..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/commands/wheel.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os -import shutil - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import RequirementCommand, with_cleanup -from pip._internal.exceptions import CommandError -from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.misc import ensure_dir, normalize_path -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel_builder import build, should_build_for_wheel_command - -if MYPY_CHECK_RUNNING: - from optparse import Values - from typing import Any, List - - -logger = logging.getLogger(__name__) - - -class WheelCommand(RequirementCommand): - """ - Build Wheel archives for your requirements and dependencies. - - Wheel is a built-package format, and offers the advantage of not - recompiling your software during every install. For more details, see the - wheel docs: https://wheel.readthedocs.io/en/latest/ - - Requirements: setuptools>=0.8, and wheel. - - 'pip wheel' uses the bdist_wheel setuptools extension from the wheel - package to build individual wheels. - - """ - - usage = """ - %prog [options] ... - %prog [options] -r ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - def __init__(self, *args, **kw): - super(WheelCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '-w', '--wheel-dir', - dest='wheel_dir', - metavar='dir', - default=os.curdir, - help=("Build wheels into , where the default is the " - "current working directory."), - ) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option( - '--build-option', - dest='build_options', - metavar='options', - action='append', - help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", - ) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.progress_bar()) - - cmd_opts.add_option( - '--global-option', - dest='global_options', - action='append', - metavar='options', - help="Extra global options to be supplied to the setup.py " - "call before the 'bdist_wheel' command.") - - cmd_opts.add_option( - '--pre', - action='store_true', - default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), - ) - - cmd_opts.add_option(cmdoptions.require_hashes()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - @with_cleanup - def run(self, options, args): - # type: (Values, List[Any]) -> None - cmdoptions.check_install_build_global(options) - - session = self.get_default_session(options) - - finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - - options.wheel_dir = normalize_path(options.wheel_dir) - ensure_dir(options.wheel_dir) - - req_tracker = self.enter_context(get_requirement_tracker()) - - directory = TempDirectory( - options.build_dir, - delete=build_delete, - kind="wheel", - globally_managed=True, - ) - - reqs = self.get_requirements(args, options, finder, session) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - req_tracker=req_tracker, - session=session, - finder=finder, - wheel_download_dir=options.wheel_dir, - use_user_site=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - ignore_requires_python=options.ignore_requires_python, - use_pep517=options.use_pep517, - ) - - self.trace_basic_info(finder) - - requirement_set = resolver.resolve( - reqs, check_supported_wheels=True - ) - - reqs_to_build = [ - r for r in requirement_set.requirements.values() - if should_build_for_wheel_command(r) - ] - - # build wheels - build_successes, build_failures = build( - reqs_to_build, - wheel_cache=wheel_cache, - build_options=options.build_options or [], - global_options=options.global_options or [], - ) - for req in build_successes: - assert req.link and req.link.is_wheel - assert req.local_file_path - # copy from cache to target directory - try: - shutil.copy(req.local_file_path, options.wheel_dir) - except OSError as e: - logger.warning( - "Building wheel for %s failed: %s", - req.name, e, - ) - build_failures.append(req) - if len(build_failures) != 0: - raise CommandError( - "Failed to build one or more wheels" - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/configuration.py b/env/lib/python3.8/site-packages/pip/_internal/configuration.py deleted file mode 100644 index 2648b8af..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/configuration.py +++ /dev/null @@ -1,426 +0,0 @@ -"""Configuration management setup - -Some terminology: -- name - As written in config files. -- value - Value associated with a name -- key - Name combined with it's section (section.name) -- variant - A single word describing where the configuration key-value pair came from -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import locale -import logging -import os -import sys - -from pip._vendor.six.moves import configparser - -from pip._internal.exceptions import ( - ConfigurationError, - ConfigurationFileCouldNotBeLoaded, -) -from pip._internal.utils import appdirs -from pip._internal.utils.compat import WINDOWS, expanduser -from pip._internal.utils.misc import ensure_dir, enum -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Dict, Iterable, List, NewType, Optional, Tuple - ) - - RawConfigParser = configparser.RawConfigParser # Shorthand - Kind = NewType("Kind", str) - -logger = logging.getLogger(__name__) - - -# NOTE: Maybe use the optionx attribute to normalize keynames. -def _normalize_name(name): - # type: (str) -> str - """Make a name consistent regardless of source (environment or file) - """ - name = name.lower().replace('_', '-') - if name.startswith('--'): - name = name[2:] # only prefer long opts - return name - - -def _disassemble_key(name): - # type: (str) -> List[str] - if "." not in name: - error_message = ( - "Key does not contain dot separated section and key. " - "Perhaps you wanted to use 'global.{}' instead?" - ).format(name) - raise ConfigurationError(error_message) - return name.split(".", 1) - - -# The kinds of configurations there are. -kinds = enum( - USER="user", # User Specific - GLOBAL="global", # System Wide - SITE="site", # [Virtual] Environment Specific - ENV="env", # from PIP_CONFIG_FILE - ENV_VAR="env-var", # from Environment Variables -) - - -CONFIG_BASENAME = 'pip.ini' if WINDOWS else 'pip.conf' - - -def get_configuration_files(): - # type: () -> Dict[Kind, List[str]] - global_config_files = [ - os.path.join(path, CONFIG_BASENAME) - for path in appdirs.site_config_dirs('pip') - ] - - site_config_file = os.path.join(sys.prefix, CONFIG_BASENAME) - legacy_config_file = os.path.join( - expanduser('~'), - 'pip' if WINDOWS else '.pip', - CONFIG_BASENAME, - ) - new_config_file = os.path.join( - appdirs.user_config_dir("pip"), CONFIG_BASENAME - ) - return { - kinds.GLOBAL: global_config_files, - kinds.SITE: [site_config_file], - kinds.USER: [legacy_config_file, new_config_file], - } - - -class Configuration(object): - """Handles management of configuration. - - Provides an interface to accessing and managing configuration files. - - This class converts provides an API that takes "section.key-name" style - keys and stores the value associated with it as "key-name" under the - section "section". - - This allows for a clean interface wherein the both the section and the - key-name are preserved in an easy to manage form in the configuration files - and the data stored is also nice. - """ - - def __init__(self, isolated, load_only=None): - # type: (bool, Kind) -> None - super(Configuration, self).__init__() - - _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.SITE, None] - if load_only not in _valid_load_only: - raise ConfigurationError( - "Got invalid value for load_only - should be one of {}".format( - ", ".join(map(repr, _valid_load_only[:-1])) - ) - ) - self.isolated = isolated # type: bool - self.load_only = load_only # type: Optional[Kind] - - # The order here determines the override order. - self._override_order = [ - kinds.GLOBAL, kinds.USER, kinds.SITE, kinds.ENV, kinds.ENV_VAR - ] - - self._ignore_env_names = ["version", "help"] - - # Because we keep track of where we got the data from - self._parsers = { - variant: [] for variant in self._override_order - } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] - self._config = { - variant: {} for variant in self._override_order - } # type: Dict[Kind, Dict[str, Any]] - self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] - - def load(self): - # type: () -> None - """Loads configuration from configuration files and environment - """ - self._load_config_files() - if not self.isolated: - self._load_environment_vars() - - def get_file_to_edit(self): - # type: () -> Optional[str] - """Returns the file with highest priority in configuration - """ - assert self.load_only is not None, \ - "Need to be specified a file to be editing" - - try: - return self._get_parser_to_modify()[0] - except IndexError: - return None - - def items(self): - # type: () -> Iterable[Tuple[str, Any]] - """Returns key-value pairs like dict.items() representing the loaded - configuration - """ - return self._dictionary.items() - - def get_value(self, key): - # type: (str) -> Any - """Get a value from the configuration. - """ - try: - return self._dictionary[key] - except KeyError: - raise ConfigurationError("No such key - {}".format(key)) - - def set_value(self, key, value): - # type: (str, Any) -> None - """Modify a value in the configuration. - """ - self._ensure_have_load_only() - - fname, parser = self._get_parser_to_modify() - - if parser is not None: - section, name = _disassemble_key(key) - - # Modify the parser and the configuration - if not parser.has_section(section): - parser.add_section(section) - parser.set(section, name, value) - - self._config[self.load_only][key] = value - self._mark_as_modified(fname, parser) - - def unset_value(self, key): - # type: (str) -> None - """Unset a value in the configuration. - """ - self._ensure_have_load_only() - - if key not in self._config[self.load_only]: - raise ConfigurationError("No such key - {}".format(key)) - - fname, parser = self._get_parser_to_modify() - - if parser is not None: - section, name = _disassemble_key(key) - - # Remove the key in the parser - modified_something = False - if parser.has_section(section): - # Returns whether the option was removed or not - modified_something = parser.remove_option(section, name) - - if modified_something: - # name removed from parser, section may now be empty - section_iter = iter(parser.items(section)) - try: - val = next(section_iter) - except StopIteration: - val = None - - if val is None: - parser.remove_section(section) - - self._mark_as_modified(fname, parser) - else: - raise ConfigurationError( - "Fatal Internal error [id=1]. Please report as a bug." - ) - - del self._config[self.load_only][key] - - def save(self): - # type: () -> None - """Save the current in-memory state. - """ - self._ensure_have_load_only() - - for fname, parser in self._modified_parsers: - logger.info("Writing to %s", fname) - - # Ensure directory exists. - ensure_dir(os.path.dirname(fname)) - - with open(fname, "w") as f: - parser.write(f) - - # - # Private routines - # - - def _ensure_have_load_only(self): - # type: () -> None - if self.load_only is None: - raise ConfigurationError("Needed a specific file to be modifying.") - logger.debug("Will be working with %s variant only", self.load_only) - - @property - def _dictionary(self): - # type: () -> Dict[str, Any] - """A dictionary representing the loaded configuration. - """ - # NOTE: Dictionaries are not populated if not loaded. So, conditionals - # are not needed here. - retval = {} - - for variant in self._override_order: - retval.update(self._config[variant]) - - return retval - - def _load_config_files(self): - # type: () -> None - """Loads configuration from configuration files - """ - config_files = dict(self._iter_config_files()) - if config_files[kinds.ENV][0:1] == [os.devnull]: - logger.debug( - "Skipping loading configuration files due to " - "environment's PIP_CONFIG_FILE being os.devnull" - ) - return - - for variant, files in config_files.items(): - for fname in files: - # If there's specific variant set in `load_only`, load only - # that variant, not the others. - if self.load_only is not None and variant != self.load_only: - logger.debug( - "Skipping file '%s' (variant: %s)", fname, variant - ) - continue - - parser = self._load_file(variant, fname) - - # Keeping track of the parsers used - self._parsers[variant].append((fname, parser)) - - def _load_file(self, variant, fname): - # type: (Kind, str) -> RawConfigParser - logger.debug("For variant '%s', will try loading '%s'", variant, fname) - parser = self._construct_parser(fname) - - for section in parser.sections(): - items = parser.items(section) - self._config[variant].update(self._normalized_keys(section, items)) - - return parser - - def _construct_parser(self, fname): - # type: (str) -> RawConfigParser - parser = configparser.RawConfigParser() - # If there is no such file, don't bother reading it but create the - # parser anyway, to hold the data. - # Doing this is useful when modifying and saving files, where we don't - # need to construct a parser. - if os.path.exists(fname): - try: - parser.read(fname) - except UnicodeDecodeError: - # See https://github.com/pypa/pip/issues/4963 - raise ConfigurationFileCouldNotBeLoaded( - reason="contains invalid {} characters".format( - locale.getpreferredencoding(False) - ), - fname=fname, - ) - except configparser.Error as error: - # See https://github.com/pypa/pip/issues/4893 - raise ConfigurationFileCouldNotBeLoaded(error=error) - return parser - - def _load_environment_vars(self): - # type: () -> None - """Loads configuration from environment variables - """ - self._config[kinds.ENV_VAR].update( - self._normalized_keys(":env:", self._get_environ_vars()) - ) - - def _normalized_keys(self, section, items): - # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] - """Normalizes items to construct a dictionary with normalized keys. - - This routine is where the names become keys and are made the same - regardless of source - configuration files or environment. - """ - normalized = {} - for name, val in items: - key = section + "." + _normalize_name(name) - normalized[key] = val - return normalized - - def _get_environ_vars(self): - # type: () -> Iterable[Tuple[str, str]] - """Returns a generator with all environmental vars with prefix PIP_""" - for key, val in os.environ.items(): - should_be_yielded = ( - key.startswith("PIP_") and - key[4:].lower() not in self._ignore_env_names - ) - if should_be_yielded: - yield key[4:].lower(), val - - # XXX: This is patched in the tests. - def _iter_config_files(self): - # type: () -> Iterable[Tuple[Kind, List[str]]] - """Yields variant and configuration files associated with it. - - This should be treated like items of a dictionary. - """ - # SMELL: Move the conditions out of this function - - # environment variables have the lowest priority - config_file = os.environ.get('PIP_CONFIG_FILE', None) - if config_file is not None: - yield kinds.ENV, [config_file] - else: - yield kinds.ENV, [] - - config_files = get_configuration_files() - - # at the base we have any global configuration - yield kinds.GLOBAL, config_files[kinds.GLOBAL] - - # per-user configuration next - should_load_user_config = not self.isolated and not ( - config_file and os.path.exists(config_file) - ) - if should_load_user_config: - # The legacy config file is overridden by the new config file - yield kinds.USER, config_files[kinds.USER] - - # finally virtualenv configuration first trumping others - yield kinds.SITE, config_files[kinds.SITE] - - def _get_parser_to_modify(self): - # type: () -> Tuple[str, RawConfigParser] - # Determine which parser to modify - parsers = self._parsers[self.load_only] - if not parsers: - # This should not happen if everything works correctly. - raise ConfigurationError( - "Fatal Internal error [id=2]. Please report as a bug." - ) - - # Use the highest priority parser. - return parsers[-1] - - # XXX: This is patched in the tests. - def _mark_as_modified(self, fname, parser): - # type: (str, RawConfigParser) -> None - file_parser_tuple = (fname, parser) - if file_parser_tuple not in self._modified_parsers: - self._modified_parsers.append(file_parser_tuple) - - def __repr__(self): - # type: () -> str - return "{}({!r})".format(self.__class__.__name__, self._dictionary) diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py deleted file mode 100644 index d5c1afc5..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from pip._internal.distributions.sdist import SourceDistribution -from pip._internal.distributions.wheel import WheelDistribution -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from pip._internal.distributions.base import AbstractDistribution - from pip._internal.req.req_install import InstallRequirement - - -def make_distribution_for_install_requirement(install_req): - # type: (InstallRequirement) -> AbstractDistribution - """Returns a Distribution for the given InstallRequirement - """ - # Editable requirements will always be source distributions. They use the - # legacy logic until we create a modern standard for them. - if install_req.editable: - return SourceDistribution(install_req) - - # If it's a wheel, it's a WheelDistribution - if install_req.is_wheel: - return WheelDistribution(install_req) - - # Otherwise, a SourceDistribution - return SourceDistribution(install_req) diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index f5fd59e4c12dc389d7be38805e1ebea5d1601d2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 812 zcmaJ<%Wl*#6t(l3%uI_!)fECMNNlp0WWfrls)~lHt$-1lQ3cJ$N+zZ?wLPirPz~y? z75~ClAn_U5vf>w5ah)=dDH1oj)_olNe-hKW?zPbo~w@KF=NcO<>D_BZY zVvYpPFt)M79pPqf8@t>Se&%CDeYFQYj|ZZc_1d1#L($Lr5C>)N24#aXoT0e?15QLS zZnkENTFvPTrj24nZP-FW_5Ry4O8K4Q*6WiuCuDrMKYmH3$CJs?ue^e_1!0*k#Sq$M+X!Kt$BO~^F4v|<%pfE~z?-TpUG^x_Lr z_JV#Mrbbk0#i~&)t9*V=%Tc>$^sFwHPm3kDy_7I%sFFEP%g!`)N}$0EAxX7tVv(Oy z((M!YaR9WlvYe}7Sz_Hjk08LIYh7(XZ4wWg$3U0-p-Z~Q=|s0_EAGFzzp9%D>*v8M z;5sqOipf*u0cR7f1J((PTvO!(EPJ#L12qZwN}UP-(`sm^+F6E{Bis>-vgUNxz6@=p LZeaKv&#vw-`9m1Zeg`aF?{T4)-S{ zH@1SDYNI*#4cen$qmQxIp85(sb%v50DK$)C>EVzw{AT7G`q^O6BQSpX?JxFwi;%x@ zu{uCUzJt$bm;@12kr@AaisoMIQIvh<=Rq7$A_M&t)`4o}?YQmsTB?(Wap>f>>gK(; z=j4vMlK102*m#m04o>JpB0|wUC88@gPW%%ZZwk6chP{8_UNRZdX26ADxwJf0+!#MW^IgBH7mv0SMq@@1WAnaje0 zcJP>|FZhA{AuEK`Dc-j_{KdlD13{9Q3KDyQ#{OHfPlYG^(=ZNX>#!{X(K;o7yyI4F z(Q&KrEeS~6g;>Jo=5_*rcxqRH@qtIkc9d`&Aj;;Ld7@;*waxay z+>Cp@2*%T?jP$!;jI-p$%ufGr3D&r;RC#2+nVUzW=txF+ZETdlHr`;%NJuMno)xfI zcOMlzm+oG;`Ziz$1}V~r0i z8G21%q}tbg*gK<5moY~-#?HvU_qS|bZB4CJYdU3$CG-a(*Y1k^}&*6-5Y4%^= zy%6K&_9>QQIZ(a~xxNkuhQ7nuwD;XR(`+VnrUc7OsW{T|{Qz!NT2@@kHQ4R}M525N z9+&vSK)t8vmum*Ves3d+0Vg`D|T} zr8*uj-U&9ZobKSk&i3~^kDzOt_Pn`W1S>(i@EsGwd-Lpmixe?Ph0yE6FQ70}`1v9I E4}G~H`Tzg` diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc deleted file mode 100644 index 1af0aa6a7e4569ce9177080edae6e6462a6561bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1208 zcmaJ=&2H2%5O#hxNw>QoDnJ4W6mi=_vxjm)La3-fsSr!mABpB-Iq~dnTIZ*B0&K;N z3h^p^4IU#`PP_r)#5lXHvZ$&hkH?ndBGq*Mn}?$8j)Cl+SZeewLSh2EZ|U=Hu0ZNv1LQ zO!?&$dcf3^ZKz96!P>3?^IWm*i2q*$*qjRg4m=P7_#e^y1a zjc6uxY)F%=1c~$yc}p!dyka3JX7%FIJ-wFW;N}9c zr7tgr_OF2J&z6&YA~gdIu7M?2(XX9x^HJ2dqbd=cCMp*V(M{6a^mX2&xj?YgF-@Ul zoR#c8rd+nZaeeDI-X9H|+M_gMDNtH>DNS=;3GMeNJ*}8nL|jUF9#blBX&iU7(IT~s zZdSTzG&<#=@eJGX?B;AVSgn1OE4Y#?XbYf%h$)a-g8Jcd8vcAj1?8+rvWe8x*3M$1 zsSO`A*`FZexeS&RmK~k^WVxEA{7bO-FX&tWse5g@Y@unuHT-+e=ajtAnks$XGkT_t H6IbgWrtne7 diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc deleted file mode 100644 index 56f086a1bf0b8d454308c0ed99235da02680c1ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3471 zcmbtWTaO#J6((m!qmfqHi@bJHCvjOj1**c<#!cNDT*Ileb%QpGtv5*%A;ow!Bm$RUVl^B9sdH0?4iRKiU1nzxAu_ zTfg@2e7Ljo-p=i|rR_aY=*kC!JjOMR7tU$!2H`!}{>v!kLWU^n;$y+!CVc99&U9Rs2M2<|!aR^hd8P`Hv;9o6;sAEDR0ytEB8q?qMKC9@ywpRnB4a&a81)4hD<}lN z%mi3WNH$PW+Go4lyX@N4A2VQCP5_O?q924u?5+~UAn)WyO!WJHle}1p;gH??+l{syWqVp&m zN=dBY)vw=2=bLwjHtw7~=wCQC`u+eqbA74l9a`Du$Qs)tTfR9W6MICbw4_X&DM4@9 zBeDV8+7;P^pFR_30r&HxTxN$NEc_x%VqG67;pZZUtI_Mexd%T|S?L0Ly@Z7D=QrPW zB!mK@-F*XHz1BnTTG+9w4zj`Nj4-Azn+@Fe#+>1zbx*lpfFD|LV}0O+j|U$@1?{NL1A;y$pVNJCCT>0P#@17MNDe95kdu2gb+NEMqlJA;aNc(e z)tOXA6zDd0rVz(wbFTSUr}R_nk7VpTC6bRUUU^E6A?}SF`Pagm)VNtSg&8xda&J;E zR*FW^9687I*qTzLl^nmg39D9l?U;@$W@c^dj$9+v-%zTNJ6Ru9ru2(d;O|a0res|G z9l1t+OYV@5$@AV^zR`kgf1%O>>FT9)vlXb7!&i6%wL+}4n>$OUL-?Wj&YF-M;?RM4k9TqHji1DrTcLd77W8JdpsXP1Tg`4{4@5L3l+*J#~3~C46Vy-DN5i? zS5Rd95KtrX`*WXKV-TK`2?4FGsr3=~$9+Hnh-VGYKOVD4u_z6*B!}qNi^c5pF(wcf zqF@pfZChKNw{$HkQ-t8!eHcKj;4ebFb{#|Dqg>v&h9aOD9m_o#?!E-bFFIW3dYpwp ztZsCC8ARZjbN$tG$|-x0Xl226dVRilZY;gBU@C|LuYo9KC~yw5DAlgYBr1R+f@6ON ze#=aNyVA{4e;+et+Sg5ic@bRJB*15uURgNS1cwE8Uw=`J%W#I;gofDGiRC!dp%!?# z`<45p>kWVYf0;;Evj;-P!O`%ISsur{^L5k>FV1q&*0rlYVQP@)#tdx1mTLIJ_akNU zR=IzX21sG2QM7|m)ZqBLsx!P>rco1L8P5RWX;v_mi!jxqv^OX4x^lznG z;eiP6Ezg}@R07hHZ`Nox&iZ{Jb@gE&Q_xjj!V~Ny$h8BNij;4{Sfa1%)iQ(mGiCLL z8uTE|g#c2&EZ_9&n0e>I`+#Y`6xEoj?Ul%V1v!2nn=8n+nv@{W?u%_5PC%ms)E$Y%m4#P|TgNy96tJ?GZG)RQ+>$>kJ86U*hZ}|TGK@iU3%EulK6U?{}_0OZutN`}Qa!6vSp=*G&-x%o18_4}_Y|v6KGpzQm Zm$!2R%Ug908qdPJH!mP$9Y;_O{TGI=0aXA1 diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index db455b9abdfa2101e6918afcf5fb50390d31af7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1560 zcmaJ>&5j&35VregdUi6qNmd{M63AL{8Hw#d;zvS4DABSBh%gG9M4R-*@w7d=ow$G2 zb`xe4E+pcHcn3J~8azf{Iq?cypvtow^#q7pu6Enya@F^J?t9zYBLeOIkH7Psn2(WY-nyc$ zV1D=O2e%*agD(ybzT!vsX0tD6H(~bO=J5$P%GRyPmF2Rxhc9ZwpPVYC!EgLhwC&p> ze=JVajiQpu1f2D-90TVleMy}svWD8l1x-f23s3p1lG=kU2nH67ZsZ;2xC<4 z^pdqz17#?g`cOHAWG@<4fK(qqw|BujC6CA>YR4}4f%_A;HTi{z3-`u zpPqZHSDuB(Bp@G=Z^#k(mE7^~`$UFNd9?cFRxPAu?o_c-IU$7;Y+>rs&#bFn0I{s7 zTn!#&ZI)1=WJbBxQ~-@n9g*mx2fKx1tp!*L_nwEwD7`GI69$0bVZG3`c@e{?vlhT9 z0rfQ|9%A5sB($!dfXY7pa5foqAvkuIb)5^%F+JW0ciQb-w^kX%{Lq-%bWtTrWe`aN zcZE!XF0x85I=cFem@6>z*WuKa&9o_+{R=AgePa8cwDaW$^QFeMDTm^fsf3>P1z@M% zHEovNJ15HV|5x%Z9A)u5l8l3KuuB6PkO3L|y?X!nW!@1$S3 z7YQ43j%0A&jW{oB*#c+08*_fv3Vptka4zedbAx!9*U=zoJ%fpwA(%0AI{-7JQ9Qij z=Vp`bE?E@~>cNxVF(5B}L0-B+UOE?`6-2OmYts#WSlXs;*??LNqT0RrUk;vpud8gm z{;jHHZPE=H7|gNT+uV None - super(AbstractDistribution, self).__init__() - self.req = req - - @abc.abstractmethod - def get_pkg_resources_distribution(self): - # type: () -> Optional[Distribution] - raise NotImplementedError() - - @abc.abstractmethod - def prepare_distribution_metadata(self, finder, build_isolation): - # type: (PackageFinder, bool) -> None - raise NotImplementedError() diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/installed.py b/env/lib/python3.8/site-packages/pip/_internal/distributions/installed.py deleted file mode 100644 index 0d15bf42..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/distributions/installed.py +++ /dev/null @@ -1,24 +0,0 @@ -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional - - from pip._vendor.pkg_resources import Distribution - from pip._internal.index.package_finder import PackageFinder - - -class InstalledDistribution(AbstractDistribution): - """Represents an installed package. - - This does not need any preparation as the required information has already - been computed. - """ - - def get_pkg_resources_distribution(self): - # type: () -> Optional[Distribution] - return self.req.satisfied_by - - def prepare_distribution_metadata(self, finder, build_isolation): - # type: (PackageFinder, bool) -> None - pass diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py b/env/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py deleted file mode 100644 index be3d7d97..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/distributions/sdist.py +++ /dev/null @@ -1,104 +0,0 @@ -import logging - -from pip._internal.build_env import BuildEnvironment -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.exceptions import InstallationError -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Set, Tuple - - from pip._vendor.pkg_resources import Distribution - from pip._internal.index.package_finder import PackageFinder - - -logger = logging.getLogger(__name__) - - -class SourceDistribution(AbstractDistribution): - """Represents a source distribution. - - The preparation step for these needs metadata for the packages to be - generated, either using PEP 517 or using the legacy `setup.py egg_info`. - """ - - def get_pkg_resources_distribution(self): - # type: () -> Distribution - return self.req.get_dist() - - def prepare_distribution_metadata(self, finder, build_isolation): - # type: (PackageFinder, bool) -> None - # Load pyproject.toml, to determine whether PEP 517 is to be used - self.req.load_pyproject_toml() - - # Set up the build isolation, if this requirement should be isolated - should_isolate = self.req.use_pep517 and build_isolation - if should_isolate: - self._setup_isolation(finder) - - self.req.prepare_metadata() - - def _setup_isolation(self, finder): - # type: (PackageFinder) -> None - def _raise_conflicts(conflicting_with, conflicting_reqs): - # type: (str, Set[Tuple[str, str]]) -> None - format_string = ( - "Some build dependencies for {requirement} " - "conflict with {conflicting_with}: {description}." - ) - error_message = format_string.format( - requirement=self.req, - conflicting_with=conflicting_with, - description=', '.join( - '{} is incompatible with {}'.format(installed, wanted) - for installed, wanted in sorted(conflicting) - ) - ) - raise InstallationError(error_message) - - # Isolate in a BuildEnvironment and install the build-time - # requirements. - pyproject_requires = self.req.pyproject_requires - assert pyproject_requires is not None - - self.req.build_env = BuildEnvironment() - self.req.build_env.install_requirements( - finder, pyproject_requires, 'overlay', - "Installing build dependencies" - ) - conflicting, missing = self.req.build_env.check_requirements( - self.req.requirements_to_check - ) - if conflicting: - _raise_conflicts("PEP 517/518 supported requirements", - conflicting) - if missing: - logger.warning( - "Missing build requirements in pyproject.toml for %s.", - self.req, - ) - logger.warning( - "The project does not specify a build backend, and " - "pip cannot fall back to setuptools without %s.", - " and ".join(map(repr, sorted(missing))) - ) - # Install any extra build dependencies that the backend requests. - # This must be done in a second pass, as the pyproject.toml - # dependencies must be installed before we can call the backend. - with self.req.build_env: - runner = runner_with_spinner_message( - "Getting requirements to build wheel" - ) - backend = self.req.pep517_backend - assert backend is not None - with backend.subprocess_runner(runner): - reqs = backend.get_requires_for_build_wheel() - - conflicting, missing = self.req.build_env.check_requirements(reqs) - if conflicting: - _raise_conflicts("the backend dependencies", conflicting) - self.req.build_env.install_requirements( - finder, missing, 'normal', - "Installing backend dependencies" - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py deleted file mode 100644 index bf3482b1..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py +++ /dev/null @@ -1,36 +0,0 @@ -from zipfile import ZipFile - -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel - -if MYPY_CHECK_RUNNING: - from pip._vendor.pkg_resources import Distribution - from pip._internal.index.package_finder import PackageFinder - - -class WheelDistribution(AbstractDistribution): - """Represents a wheel distribution. - - This does not need any preparation as wheels can be directly unpacked. - """ - - def get_pkg_resources_distribution(self): - # type: () -> Distribution - """Loads the metadata from the wheel file into memory and returns a - Distribution that uses it, not relying on the wheel file or - requirement. - """ - # Set as part of preparation during download. - assert self.req.local_file_path - # Wheels are never unnamed. - assert self.req.name - - with ZipFile(self.req.local_file_path, allowZip64=True) as z: - return pkg_resources_distribution_for_wheel( - z, self.req.name, self.req.local_file_path - ) - - def prepare_distribution_metadata(self, finder, build_isolation): - # type: (PackageFinder, bool) -> None - pass diff --git a/env/lib/python3.8/site-packages/pip/_internal/exceptions.py b/env/lib/python3.8/site-packages/pip/_internal/exceptions.py deleted file mode 100644 index 8ac85485..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/exceptions.py +++ /dev/null @@ -1,308 +0,0 @@ -"""Exceptions used throughout package""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -from itertools import chain, groupby, repeat - -from pip._vendor.six import iteritems - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional - from pip._vendor.pkg_resources import Distribution - from pip._internal.req.req_install import InstallRequirement - - -class PipError(Exception): - """Base pip exception""" - - -class ConfigurationError(PipError): - """General exception in configuration""" - - -class InstallationError(PipError): - """General exception during installation""" - - -class UninstallationError(PipError): - """General exception during uninstallation""" - - -class NoneMetadataError(PipError): - """ - Raised when accessing "METADATA" or "PKG-INFO" metadata for a - pip._vendor.pkg_resources.Distribution object and - `dist.has_metadata('METADATA')` returns True but - `dist.get_metadata('METADATA')` returns None (and similarly for - "PKG-INFO"). - """ - - def __init__(self, dist, metadata_name): - # type: (Distribution, str) -> None - """ - :param dist: A Distribution object. - :param metadata_name: The name of the metadata being accessed - (can be "METADATA" or "PKG-INFO"). - """ - self.dist = dist - self.metadata_name = metadata_name - - def __str__(self): - # type: () -> str - # Use `dist` in the error message because its stringification - # includes more information, like the version and location. - return ( - 'None {} metadata found for distribution: {}'.format( - self.metadata_name, self.dist, - ) - ) - - -class DistributionNotFound(InstallationError): - """Raised when a distribution cannot be found to satisfy a requirement""" - - -class RequirementsFileParseError(InstallationError): - """Raised when a general error occurs parsing a requirements file line.""" - - -class BestVersionAlreadyInstalled(PipError): - """Raised when the most up-to-date version of a package is already - installed.""" - - -class BadCommand(PipError): - """Raised when virtualenv or a command is not found""" - - -class CommandError(PipError): - """Raised when there is an error in command-line arguments""" - - -class PreviousBuildDirError(PipError): - """Raised when there's a previous conflicting build directory""" - - -class InvalidWheelFilename(InstallationError): - """Invalid wheel filename.""" - - -class UnsupportedWheel(InstallationError): - """Unsupported wheel.""" - - -class HashErrors(InstallationError): - """Multiple HashError instances rolled into one for reporting""" - - def __init__(self): - self.errors = [] - - def append(self, error): - self.errors.append(error) - - def __str__(self): - lines = [] - self.errors.sort(key=lambda e: e.order) - for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): - lines.append(cls.head) - lines.extend(e.body() for e in errors_of_cls) - if lines: - return '\n'.join(lines) - - def __nonzero__(self): - return bool(self.errors) - - def __bool__(self): - return self.__nonzero__() - - -class HashError(InstallationError): - """ - A failure to verify a package against known-good hashes - - :cvar order: An int sorting hash exception classes by difficulty of - recovery (lower being harder), so the user doesn't bother fretting - about unpinned packages when he has deeper issues, like VCS - dependencies, to deal with. Also keeps error reports in a - deterministic order. - :cvar head: A section heading for display above potentially many - exceptions of this kind - :ivar req: The InstallRequirement that triggered this error. This is - pasted on after the exception is instantiated, because it's not - typically available earlier. - - """ - req = None # type: Optional[InstallRequirement] - head = '' - - def body(self): - """Return a summary of me for display under the heading. - - This default implementation simply prints a description of the - triggering requirement. - - :param req: The InstallRequirement that provoked this error, with - its link already populated by the resolver's _populate_link(). - - """ - return ' {}'.format(self._requirement_name()) - - def __str__(self): - return '{}\n{}'.format(self.head, self.body()) - - def _requirement_name(self): - """Return a description of the requirement that triggered me. - - This default implementation returns long description of the req, with - line numbers - - """ - return str(self.req) if self.req else 'unknown package' - - -class VcsHashUnsupported(HashError): - """A hash was provided for a version-control-system-based requirement, but - we don't have a method for hashing those.""" - - order = 0 - head = ("Can't verify hashes for these requirements because we don't " - "have a way to hash version control repositories:") - - -class DirectoryUrlHashUnsupported(HashError): - """A hash was provided for a version-control-system-based requirement, but - we don't have a method for hashing those.""" - - order = 1 - head = ("Can't verify hashes for these file:// requirements because they " - "point to directories:") - - -class HashMissing(HashError): - """A hash was needed for a requirement but is absent.""" - - order = 2 - head = ('Hashes are required in --require-hashes mode, but they are ' - 'missing from some requirements. Here is a list of those ' - 'requirements along with the hashes their downloaded archives ' - 'actually had. Add lines like these to your requirements files to ' - 'prevent tampering. (If you did not enable --require-hashes ' - 'manually, note that it turns on automatically when any package ' - 'has a hash.)') - - def __init__(self, gotten_hash): - """ - :param gotten_hash: The hash of the (possibly malicious) archive we - just downloaded - """ - self.gotten_hash = gotten_hash - - def body(self): - # Dodge circular import. - from pip._internal.utils.hashes import FAVORITE_HASH - - package = None - if self.req: - # In the case of URL-based requirements, display the original URL - # seen in the requirements file rather than the package name, - # so the output can be directly copied into the requirements file. - package = (self.req.original_link if self.req.original_link - # In case someone feeds something downright stupid - # to InstallRequirement's constructor. - else getattr(self.req, 'req', None)) - return ' {} --hash={}:{}'.format(package or 'unknown package', - FAVORITE_HASH, - self.gotten_hash) - - -class HashUnpinned(HashError): - """A requirement had a hash specified but was not pinned to a specific - version.""" - - order = 3 - head = ('In --require-hashes mode, all requirements must have their ' - 'versions pinned with ==. These do not:') - - -class HashMismatch(HashError): - """ - Distribution file hash values don't match. - - :ivar package_name: The name of the package that triggered the hash - mismatch. Feel free to write to this after the exception is raise to - improve its error message. - - """ - order = 4 - head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' - 'FILE. If you have updated the package versions, please update ' - 'the hashes. Otherwise, examine the package contents carefully; ' - 'someone may have tampered with them.') - - def __init__(self, allowed, gots): - """ - :param allowed: A dict of algorithm names pointing to lists of allowed - hex digests - :param gots: A dict of algorithm names pointing to hashes we - actually got from the files under suspicion - """ - self.allowed = allowed - self.gots = gots - - def body(self): - return ' {}:\n{}'.format(self._requirement_name(), - self._hash_comparison()) - - def _hash_comparison(self): - """ - Return a comparison of actual and expected hash values. - - Example:: - - Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde - or 123451234512345123451234512345123451234512345 - Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef - - """ - def hash_then_or(hash_name): - # For now, all the decent hashes have 6-char names, so we can get - # away with hard-coding space literals. - return chain([hash_name], repeat(' or')) - - lines = [] - for hash_name, expecteds in iteritems(self.allowed): - prefix = hash_then_or(hash_name) - lines.extend((' Expected {} {}'.format(next(prefix), e)) - for e in expecteds) - lines.append(' Got {}\n'.format( - self.gots[hash_name].hexdigest())) - return '\n'.join(lines) - - -class UnsupportedPythonVersion(InstallationError): - """Unsupported python version according to Requires-Python package - metadata.""" - - -class ConfigurationFileCouldNotBeLoaded(ConfigurationError): - """When there are errors while loading a configuration file - """ - - def __init__(self, reason="could not be loaded", fname=None, error=None): - super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) - self.reason = reason - self.fname = fname - self.error = error - - def __str__(self): - if self.fname is not None: - message_part = " in {}.".format(self.fname) - else: - assert self.error is not None - message_part = ".\n{}\n".format(self.error.message) - return "Configuration file {}{}".format(self.reason, message_part) diff --git a/env/lib/python3.8/site-packages/pip/_internal/index/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/index/__init__.py deleted file mode 100644 index 7a17b7b3..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/index/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Index interaction code -""" diff --git a/env/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 5635028197d9fb7b87d9a650fab8772d328fe903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 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 Q>I8Bx0k&@Pc>n+a diff --git a/env/lib/python3.8/site-packages/pip/_internal/index/collector.py b/env/lib/python3.8/site-packages/pip/_internal/index/collector.py deleted file mode 100644 index e2c800c2..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/index/collector.py +++ /dev/null @@ -1,661 +0,0 @@ -""" -The main purpose of this module is to expose LinkCollector.collect_links(). -""" - -import cgi -import functools -import itertools -import logging -import mimetypes -import os -import re -from collections import OrderedDict - -from pip._vendor import html5lib, requests -from pip._vendor.distlib.compat import unescape -from pip._vendor.requests.exceptions import HTTPError, RetryError, SSLError -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.models.link import Link -from pip._internal.utils.filetypes import ARCHIVE_EXTENSIONS -from pip._internal.utils.misc import pairwise, redact_auth_from_url -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url, url_to_path -from pip._internal.vcs import is_url, vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Callable, Iterable, List, MutableMapping, Optional, - Protocol, Sequence, Tuple, TypeVar, Union, - ) - import xml.etree.ElementTree - - from pip._vendor.requests import Response - - from pip._internal.models.search_scope import SearchScope - from pip._internal.network.session import PipSession - - HTMLElement = xml.etree.ElementTree.Element - ResponseHeaders = MutableMapping[str, str] - - # Used in the @lru_cache polyfill. - F = TypeVar('F') - - class LruCache(Protocol): - def __call__(self, maxsize=None): - # type: (Optional[int]) -> Callable[[F], F] - raise NotImplementedError - - -logger = logging.getLogger(__name__) - - -# Fallback to noop_lru_cache in Python 2 -# TODO: this can be removed when python 2 support is dropped! -def noop_lru_cache(maxsize=None): - # type: (Optional[int]) -> Callable[[F], F] - def _wrapper(f): - # type: (F) -> F - return f - return _wrapper - - -_lru_cache = getattr(functools, "lru_cache", noop_lru_cache) # type: LruCache - - -def _match_vcs_scheme(url): - # type: (str) -> Optional[str] - """Look for VCS schemes in the URL. - - Returns the matched VCS scheme, or None if there's no match. - """ - for scheme in vcs.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in '+:': - return scheme - return None - - -def _is_url_like_archive(url): - # type: (str) -> bool - """Return whether the URL looks like an archive. - """ - filename = Link(url).filename - for bad_ext in ARCHIVE_EXTENSIONS: - if filename.endswith(bad_ext): - return True - return False - - -class _NotHTML(Exception): - def __init__(self, content_type, request_desc): - # type: (str, str) -> None - super(_NotHTML, self).__init__(content_type, request_desc) - self.content_type = content_type - self.request_desc = request_desc - - -def _ensure_html_header(response): - # type: (Response) -> None - """Check the Content-Type header to ensure the response contains HTML. - - Raises `_NotHTML` if the content type is not text/html. - """ - content_type = response.headers.get("Content-Type", "") - if not content_type.lower().startswith("text/html"): - raise _NotHTML(content_type, response.request.method) - - -class _NotHTTP(Exception): - pass - - -def _ensure_html_response(url, session): - # type: (str, PipSession) -> None - """Send a HEAD request to the URL, and ensure the response contains HTML. - - Raises `_NotHTTP` if the URL is not available for a HEAD request, or - `_NotHTML` if the content type is not text/html. - """ - scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) - if scheme not in {'http', 'https'}: - raise _NotHTTP() - - resp = session.head(url, allow_redirects=True) - resp.raise_for_status() - - _ensure_html_header(resp) - - -def _get_html_response(url, session): - # type: (str, PipSession) -> Response - """Access an HTML page with GET, and return the response. - - This consists of three parts: - - 1. If the URL looks suspiciously like an archive, send a HEAD first to - check the Content-Type is HTML, to avoid downloading a large file. - Raise `_NotHTTP` if the content type cannot be determined, or - `_NotHTML` if it is not HTML. - 2. Actually perform the request. Raise HTTP exceptions on network failures. - 3. Check the Content-Type header to make sure we got HTML, and raise - `_NotHTML` otherwise. - """ - if _is_url_like_archive(url): - _ensure_html_response(url, session=session) - - logger.debug('Getting page %s', redact_auth_from_url(url)) - - resp = session.get( - url, - headers={ - "Accept": "text/html", - # We don't want to blindly returned cached data for - # /simple/, because authors generally expecting that - # twine upload && pip install will function, but if - # they've done a pip install in the last ~10 minutes - # it won't. Thus by setting this to zero we will not - # blindly use any cached data, however the benefit of - # using max-age=0 instead of no-cache, is that we will - # still support conditional requests, so we will still - # minimize traffic sent in cases where the page hasn't - # changed at all, we will just always incur the round - # trip for the conditional GET now instead of only - # once per 10 minutes. - # For more information, please see pypa/pip#5670. - "Cache-Control": "max-age=0", - }, - ) - resp.raise_for_status() - - # The check for archives above only works if the url ends with - # something that looks like an archive. However that is not a - # requirement of an url. Unless we issue a HEAD request on every - # url we cannot know ahead of time for sure if something is HTML - # or not. However we can check after we've downloaded it. - _ensure_html_header(resp) - - return resp - - -def _get_encoding_from_headers(headers): - # type: (ResponseHeaders) -> Optional[str] - """Determine if we have any encoding information in our headers. - """ - if headers and "Content-Type" in headers: - content_type, params = cgi.parse_header(headers["Content-Type"]) - if "charset" in params: - return params['charset'] - return None - - -def _determine_base_url(document, page_url): - # type: (HTMLElement, str) -> str - """Determine the HTML document's base URL. - - This looks for a ```` tag in the HTML document. If present, its href - attribute denotes the base URL of anchor tags in the document. If there is - no such tag (or if it does not have a valid href attribute), the HTML - file's URL is used as the base URL. - - :param document: An HTML document representation. The current - implementation expects the result of ``html5lib.parse()``. - :param page_url: The URL of the HTML document. - """ - for base in document.findall(".//base"): - href = base.get("href") - if href is not None: - return href - return page_url - - -def _clean_url_path_part(part): - # type: (str) -> str - """ - Clean a "part" of a URL path (i.e. after splitting on "@" characters). - """ - # We unquote prior to quoting to make sure nothing is double quoted. - return urllib_parse.quote(urllib_parse.unquote(part)) - - -def _clean_file_url_path(part): - # type: (str) -> str - """ - Clean the first part of a URL path that corresponds to a local - filesystem path (i.e. the first part after splitting on "@" characters). - """ - # We unquote prior to quoting to make sure nothing is double quoted. - # Also, on Windows the path part might contain a drive letter which - # should not be quoted. On Linux where drive letters do not - # exist, the colon should be quoted. We rely on urllib.request - # to do the right thing here. - return urllib_request.pathname2url(urllib_request.url2pathname(part)) - - -# percent-encoded: / -_reserved_chars_re = re.compile('(@|%2F)', re.IGNORECASE) - - -def _clean_url_path(path, is_local_path): - # type: (str, bool) -> str - """ - Clean the path portion of a URL. - """ - if is_local_path: - clean_func = _clean_file_url_path - else: - clean_func = _clean_url_path_part - - # Split on the reserved characters prior to cleaning so that - # revision strings in VCS URLs are properly preserved. - parts = _reserved_chars_re.split(path) - - cleaned_parts = [] - for to_clean, reserved in pairwise(itertools.chain(parts, [''])): - cleaned_parts.append(clean_func(to_clean)) - # Normalize %xx escapes (e.g. %2f -> %2F) - cleaned_parts.append(reserved.upper()) - - return ''.join(cleaned_parts) - - -def _clean_link(url): - # type: (str) -> str - """ - Make sure a link is fully quoted. - For example, if ' ' occurs in the URL, it will be replaced with "%20", - and without double-quoting other characters. - """ - # Split the URL into parts according to the general structure - # `scheme://netloc/path;parameters?query#fragment`. - result = urllib_parse.urlparse(url) - # If the netloc is empty, then the URL refers to a local filesystem path. - is_local_path = not result.netloc - path = _clean_url_path(result.path, is_local_path=is_local_path) - return urllib_parse.urlunparse(result._replace(path=path)) - - -def _create_link_from_element( - anchor, # type: HTMLElement - page_url, # type: str - base_url, # type: str -): - # type: (...) -> Optional[Link] - """ - Convert an anchor element in a simple repository page to a Link. - """ - href = anchor.get("href") - if not href: - return None - - url = _clean_link(urllib_parse.urljoin(base_url, href)) - pyrequire = anchor.get('data-requires-python') - pyrequire = unescape(pyrequire) if pyrequire else None - - yanked_reason = anchor.get('data-yanked') - if yanked_reason: - # This is a unicode string in Python 2 (and 3). - yanked_reason = unescape(yanked_reason) - - link = Link( - url, - comes_from=page_url, - requires_python=pyrequire, - yanked_reason=yanked_reason, - ) - - return link - - -class CacheablePageContent(object): - def __init__(self, page): - # type: (HTMLPage) -> None - assert page.cache_link_parsing - self.page = page - - def __eq__(self, other): - # type: (object) -> bool - return (isinstance(other, type(self)) and - self.page.url == other.page.url) - - def __hash__(self): - # type: () -> int - return hash(self.page.url) - - -def with_cached_html_pages( - fn, # type: Callable[[HTMLPage], Iterable[Link]] -): - # type: (...) -> Callable[[HTMLPage], List[Link]] - """ - Given a function that parses an Iterable[Link] from an HTMLPage, cache the - function's result (keyed by CacheablePageContent), unless the HTMLPage - `page` has `page.cache_link_parsing == False`. - """ - - @_lru_cache(maxsize=None) - def wrapper(cacheable_page): - # type: (CacheablePageContent) -> List[Link] - return list(fn(cacheable_page.page)) - - @functools.wraps(fn) - def wrapper_wrapper(page): - # type: (HTMLPage) -> List[Link] - if page.cache_link_parsing: - return wrapper(CacheablePageContent(page)) - return list(fn(page)) - - return wrapper_wrapper - - -@with_cached_html_pages -def parse_links(page): - # type: (HTMLPage) -> Iterable[Link] - """ - Parse an HTML document, and yield its anchor elements as Link objects. - """ - document = html5lib.parse( - page.content, - transport_encoding=page.encoding, - namespaceHTMLElements=False, - ) - - url = page.url - base_url = _determine_base_url(document, url) - for anchor in document.findall(".//a"): - link = _create_link_from_element( - anchor, - page_url=url, - base_url=base_url, - ) - if link is None: - continue - yield link - - -class HTMLPage(object): - """Represents one page, along with its URL""" - - def __init__( - self, - content, # type: bytes - encoding, # type: Optional[str] - url, # type: str - cache_link_parsing=True, # type: bool - ): - # type: (...) -> None - """ - :param encoding: the encoding to decode the given content. - :param url: the URL from which the HTML was downloaded. - :param cache_link_parsing: whether links parsed from this page's url - should be cached. PyPI index urls should - have this set to False, for example. - """ - self.content = content - self.encoding = encoding - self.url = url - self.cache_link_parsing = cache_link_parsing - - def __str__(self): - # type: () -> str - return redact_auth_from_url(self.url) - - -def _handle_get_page_fail( - link, # type: Link - reason, # type: Union[str, Exception] - meth=None # type: Optional[Callable[..., None]] -): - # type: (...) -> None - if meth is None: - meth = logger.debug - meth("Could not fetch URL %s: %s - skipping", link, reason) - - -def _make_html_page(response, cache_link_parsing=True): - # type: (Response, bool) -> HTMLPage - encoding = _get_encoding_from_headers(response.headers) - return HTMLPage( - response.content, - encoding=encoding, - url=response.url, - cache_link_parsing=cache_link_parsing) - - -def _get_html_page(link, session=None): - # type: (Link, Optional[PipSession]) -> Optional[HTMLPage] - if session is None: - raise TypeError( - "_get_html_page() missing 1 required keyword argument: 'session'" - ) - - url = link.url.split('#', 1)[0] - - # Check for VCS schemes that do not support lookup as web pages. - vcs_scheme = _match_vcs_scheme(url) - if vcs_scheme: - logger.debug('Cannot look at %s URL %s', vcs_scheme, link) - return None - - # Tack index.html onto file:// URLs that point to directories - scheme, _, path, _, _, _ = urllib_parse.urlparse(url) - if (scheme == 'file' and os.path.isdir(urllib_request.url2pathname(path))): - # add trailing slash if not present so urljoin doesn't trim - # final segment - if not url.endswith('/'): - url += '/' - url = urllib_parse.urljoin(url, 'index.html') - logger.debug(' file: URL is directory, getting %s', url) - - try: - resp = _get_html_response(url, session=session) - except _NotHTTP: - logger.debug( - 'Skipping page %s because it looks like an archive, and cannot ' - 'be checked by HEAD.', link, - ) - except _NotHTML as exc: - logger.debug( - 'Skipping page %s because the %s request got Content-Type: %s', - link, exc.request_desc, exc.content_type, - ) - except HTTPError as exc: - _handle_get_page_fail(link, exc) - except RetryError as exc: - _handle_get_page_fail(link, exc) - except SSLError as exc: - reason = "There was a problem confirming the ssl certificate: " - reason += str(exc) - _handle_get_page_fail(link, reason, meth=logger.info) - except requests.ConnectionError as exc: - _handle_get_page_fail(link, "connection error: {}".format(exc)) - except requests.Timeout: - _handle_get_page_fail(link, "timed out") - else: - return _make_html_page(resp, - cache_link_parsing=link.cache_link_parsing) - return None - - -def _remove_duplicate_links(links): - # type: (Iterable[Link]) -> List[Link] - """ - Return a list of links, with duplicates removed and ordering preserved. - """ - # We preserve the ordering when removing duplicates because we can. - return list(OrderedDict.fromkeys(links)) - - -def group_locations(locations, expand_dir=False): - # type: (Sequence[str], bool) -> Tuple[List[str], List[str]] - """ - Divide a list of locations into two groups: "files" (archives) and "urls." - - :return: A pair of lists (files, urls). - """ - files = [] - urls = [] - - # puts the url for the given file path into the appropriate list - def sort_path(path): - # type: (str) -> None - url = path_to_url(path) - if mimetypes.guess_type(url, strict=False)[0] == 'text/html': - urls.append(url) - else: - files.append(url) - - for url in locations: - - is_local_path = os.path.exists(url) - is_file_url = url.startswith('file:') - - if is_local_path or is_file_url: - if is_local_path: - path = url - else: - path = url_to_path(url) - if os.path.isdir(path): - if expand_dir: - path = os.path.realpath(path) - for item in os.listdir(path): - sort_path(os.path.join(path, item)) - elif is_file_url: - urls.append(url) - else: - logger.warning( - "Path '{0}' is ignored: " - "it is a directory.".format(path), - ) - elif os.path.isfile(path): - sort_path(path) - else: - logger.warning( - "Url '%s' is ignored: it is neither a file " - "nor a directory.", url, - ) - elif is_url(url): - # Only add url with clear scheme - urls.append(url) - else: - logger.warning( - "Url '%s' is ignored. It is either a non-existing " - "path or lacks a specific scheme.", url, - ) - - return files, urls - - -class CollectedLinks(object): - - """ - Encapsulates the return value of a call to LinkCollector.collect_links(). - - The return value includes both URLs to project pages containing package - links, as well as individual package Link objects collected from other - sources. - - This info is stored separately as: - - (1) links from the configured file locations, - (2) links from the configured find_links, and - (3) urls to HTML project pages, as described by the PEP 503 simple - repository API. - """ - - def __init__( - self, - files, # type: List[Link] - find_links, # type: List[Link] - project_urls, # type: List[Link] - ): - # type: (...) -> None - """ - :param files: Links from file locations. - :param find_links: Links from find_links. - :param project_urls: URLs to HTML project pages, as described by - the PEP 503 simple repository API. - """ - self.files = files - self.find_links = find_links - self.project_urls = project_urls - - -class LinkCollector(object): - - """ - Responsible for collecting Link objects from all configured locations, - making network requests as needed. - - The class's main method is its collect_links() method. - """ - - def __init__( - self, - session, # type: PipSession - search_scope, # type: SearchScope - ): - # type: (...) -> None - self.search_scope = search_scope - self.session = session - - @property - def find_links(self): - # type: () -> List[str] - return self.search_scope.find_links - - def fetch_page(self, location): - # type: (Link) -> Optional[HTMLPage] - """ - Fetch an HTML page containing package links. - """ - return _get_html_page(location, session=self.session) - - def collect_links(self, project_name): - # type: (str) -> CollectedLinks - """Find all available links for the given project name. - - :return: All the Link objects (unfiltered), as a CollectedLinks object. - """ - search_scope = self.search_scope - index_locations = search_scope.get_index_urls_locations(project_name) - index_file_loc, index_url_loc = group_locations(index_locations) - fl_file_loc, fl_url_loc = group_locations( - self.find_links, expand_dir=True, - ) - - file_links = [ - Link(url) for url in itertools.chain(index_file_loc, fl_file_loc) - ] - - # We trust every directly linked archive in find_links - find_link_links = [Link(url, '-f') for url in self.find_links] - - # We trust every url that the user has given us whether it was given - # via --index-url or --find-links. - # We want to filter out anything that does not have a secure origin. - url_locations = [ - link for link in itertools.chain( - # Mark PyPI indices as "cache_link_parsing == False" -- this - # will avoid caching the result of parsing the page for links. - (Link(url, cache_link_parsing=False) for url in index_url_loc), - (Link(url) for url in fl_url_loc), - ) - if self.session.is_secure_origin(link) - ] - - url_locations = _remove_duplicate_links(url_locations) - lines = [ - '{} location(s) to search for versions of {}:'.format( - len(url_locations), project_name, - ), - ] - for link in url_locations: - lines.append('* {}'.format(link)) - logger.debug('\n'.join(lines)) - - return CollectedLinks( - files=file_links, - find_links=find_link_links, - project_urls=url_locations, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/index/package_finder.py b/env/lib/python3.8/site-packages/pip/_internal/index/package_finder.py deleted file mode 100644 index e88ad9f5..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/index/package_finder.py +++ /dev/null @@ -1,1016 +0,0 @@ -"""Routines related to PyPI, indexes""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging -import re - -from pip._vendor.packaging import specifiers -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import parse as parse_version - -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, - DistributionNotFound, - InvalidWheelFilename, - UnsupportedWheel, -) -from pip._internal.index.collector import parse_links -from pip._internal.models.candidate import InstallationCandidate -from pip._internal.models.format_control import FormatControl -from pip._internal.models.link import Link -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.models.target_python import TargetPython -from pip._internal.models.wheel import Wheel -from pip._internal.utils.filetypes import WHEEL_EXTENSION -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import build_netloc -from pip._internal.utils.packaging import check_requires_python -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS -from pip._internal.utils.urls import url_to_path - -if MYPY_CHECK_RUNNING: - from typing import ( - FrozenSet, Iterable, List, Optional, Set, Text, Tuple, Union, - ) - - from pip._vendor.packaging.tags import Tag - from pip._vendor.packaging.version import _BaseVersion - - from pip._internal.index.collector import LinkCollector - from pip._internal.models.search_scope import SearchScope - from pip._internal.req import InstallRequirement - from pip._internal.utils.hashes import Hashes - - BuildTag = Union[Tuple[()], Tuple[int, str]] - CandidateSortingKey = ( - Tuple[int, int, int, _BaseVersion, BuildTag, Optional[int]] - ) - - -__all__ = ['FormatControl', 'BestCandidateResult', 'PackageFinder'] - - -logger = logging.getLogger(__name__) - - -def _check_link_requires_python( - link, # type: Link - version_info, # type: Tuple[int, int, int] - ignore_requires_python=False, # type: bool -): - # type: (...) -> bool - """ - Return whether the given Python version is compatible with a link's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - """ - try: - is_compatible = check_requires_python( - link.requires_python, version_info=version_info, - ) - except specifiers.InvalidSpecifier: - logger.debug( - "Ignoring invalid Requires-Python (%r) for link: %s", - link.requires_python, link, - ) - else: - if not is_compatible: - version = '.'.join(map(str, version_info)) - if not ignore_requires_python: - logger.debug( - 'Link requires a different Python (%s not in: %r): %s', - version, link.requires_python, link, - ) - return False - - logger.debug( - 'Ignoring failed Requires-Python check (%s not in: %r) ' - 'for link: %s', - version, link.requires_python, link, - ) - - return True - - -class LinkEvaluator(object): - - """ - Responsible for evaluating links for a particular project. - """ - - _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - def __init__( - self, - project_name, # type: str - canonical_name, # type: str - formats, # type: FrozenSet[str] - target_python, # type: TargetPython - allow_yanked, # type: bool - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> None - """ - :param project_name: The user supplied package name. - :param canonical_name: The canonical package name. - :param formats: The formats allowed for this package. Should be a set - with 'binary' or 'source' or both in it. - :param target_python: The target Python interpreter to use when - evaluating link compatibility. This is used, for example, to - check wheel compatibility, as well as when checking the Python - version, e.g. the Python version embedded in a link filename - (or egg fragment) and against an HTML link's optional PEP 503 - "data-requires-python" attribute. - :param allow_yanked: Whether files marked as yanked (in the sense - of PEP 592) are permitted to be candidates for install. - :param ignore_requires_python: Whether to ignore incompatible - PEP 503 "data-requires-python" values in HTML links. Defaults - to False. - """ - if ignore_requires_python is None: - ignore_requires_python = False - - self._allow_yanked = allow_yanked - self._canonical_name = canonical_name - self._ignore_requires_python = ignore_requires_python - self._formats = formats - self._target_python = target_python - - self.project_name = project_name - - def evaluate_link(self, link): - # type: (Link) -> Tuple[bool, Optional[Text]] - """ - Determine whether a link is a candidate for installation. - - :return: A tuple (is_candidate, result), where `result` is (1) a - version string if `is_candidate` is True, and (2) if - `is_candidate` is False, an optional string to log the reason - the link fails to qualify. - """ - version = None - if link.is_yanked and not self._allow_yanked: - reason = link.yanked_reason or '' - # Mark this as a unicode string to prevent "UnicodeEncodeError: - # 'ascii' codec can't encode character" in Python 2 when - # the reason contains non-ascii characters. - return (False, u'yanked for reason: {}'.format(reason)) - - if link.egg_fragment: - egg_info = link.egg_fragment - ext = link.ext - else: - egg_info, ext = link.splitext() - if not ext: - return (False, 'not a file') - if ext not in SUPPORTED_EXTENSIONS: - return (False, 'unsupported archive format: {}'.format(ext)) - if "binary" not in self._formats and ext == WHEEL_EXTENSION: - reason = 'No binaries permitted for {}'.format( - self.project_name) - return (False, reason) - if "macosx10" in link.path and ext == '.zip': - return (False, 'macosx10 one') - if ext == WHEEL_EXTENSION: - try: - wheel = Wheel(link.filename) - except InvalidWheelFilename: - return (False, 'invalid wheel filename') - if canonicalize_name(wheel.name) != self._canonical_name: - reason = 'wrong project name (not {})'.format( - self.project_name) - return (False, reason) - - supported_tags = self._target_python.get_tags() - if not wheel.supported(supported_tags): - # Include the wheel's tags in the reason string to - # simplify troubleshooting compatibility issues. - file_tags = wheel.get_formatted_file_tags() - reason = ( - "none of the wheel's tags match: {}".format( - ', '.join(file_tags) - ) - ) - return (False, reason) - - version = wheel.version - - # This should be up by the self.ok_binary check, but see issue 2700. - if "source" not in self._formats and ext != WHEEL_EXTENSION: - reason = 'No sources permitted for {}'.format(self.project_name) - return (False, reason) - - if not version: - version = _extract_version_from_fragment( - egg_info, self._canonical_name, - ) - if not version: - reason = 'Missing project version for {}'.format(self.project_name) - return (False, reason) - - match = self._py_version_re.search(version) - if match: - version = version[:match.start()] - py_version = match.group(1) - if py_version != self._target_python.py_version: - return (False, 'Python version is incorrect') - - supports_python = _check_link_requires_python( - link, version_info=self._target_python.py_version_info, - ignore_requires_python=self._ignore_requires_python, - ) - if not supports_python: - # Return None for the reason text to suppress calling - # _log_skipped_link(). - return (False, None) - - logger.debug('Found link %s, version: %s', link, version) - - return (True, version) - - -def filter_unallowed_hashes( - candidates, # type: List[InstallationCandidate] - hashes, # type: Hashes - project_name, # type: str -): - # type: (...) -> List[InstallationCandidate] - """ - Filter out candidates whose hashes aren't allowed, and return a new - list of candidates. - - If at least one candidate has an allowed hash, then all candidates with - either an allowed hash or no hash specified are returned. Otherwise, - the given candidates are returned. - - Including the candidates with no hash specified when there is a match - allows a warning to be logged if there is a more preferred candidate - with no hash specified. Returning all candidates in the case of no - matches lets pip report the hash of the candidate that would otherwise - have been installed (e.g. permitting the user to more easily update - their requirements file with the desired hash). - """ - if not hashes: - logger.debug( - 'Given no hashes to check %s links for project %r: ' - 'discarding no candidates', - len(candidates), - project_name, - ) - # Make sure we're not returning back the given value. - return list(candidates) - - matches_or_no_digest = [] - # Collect the non-matches for logging purposes. - non_matches = [] - match_count = 0 - for candidate in candidates: - link = candidate.link - if not link.has_hash: - pass - elif link.is_hash_allowed(hashes=hashes): - match_count += 1 - else: - non_matches.append(candidate) - continue - - matches_or_no_digest.append(candidate) - - if match_count: - filtered = matches_or_no_digest - else: - # Make sure we're not returning back the given value. - filtered = list(candidates) - - if len(filtered) == len(candidates): - discard_message = 'discarding no candidates' - else: - discard_message = 'discarding {} non-matches:\n {}'.format( - len(non_matches), - '\n '.join(str(candidate.link) for candidate in non_matches) - ) - - logger.debug( - 'Checked %s links for project %r against %s hashes ' - '(%s matches, %s no digest): %s', - len(candidates), - project_name, - hashes.digest_count, - match_count, - len(matches_or_no_digest) - match_count, - discard_message - ) - - return filtered - - -class CandidatePreferences(object): - - """ - Encapsulates some of the preferences for filtering and sorting - InstallationCandidate objects. - """ - - def __init__( - self, - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - ): - # type: (...) -> None - """ - :param allow_all_prereleases: Whether to allow all pre-releases. - """ - self.allow_all_prereleases = allow_all_prereleases - self.prefer_binary = prefer_binary - - -class BestCandidateResult(object): - """A collection of candidates, returned by `PackageFinder.find_best_candidate`. - - This class is only intended to be instantiated by CandidateEvaluator's - `compute_best_candidate()` method. - """ - - def __init__( - self, - candidates, # type: List[InstallationCandidate] - applicable_candidates, # type: List[InstallationCandidate] - best_candidate, # type: Optional[InstallationCandidate] - ): - # type: (...) -> None - """ - :param candidates: A sequence of all available candidates found. - :param applicable_candidates: The applicable candidates. - :param best_candidate: The most preferred candidate found, or None - if no applicable candidates were found. - """ - assert set(applicable_candidates) <= set(candidates) - - if best_candidate is None: - assert not applicable_candidates - else: - assert best_candidate in applicable_candidates - - self._applicable_candidates = applicable_candidates - self._candidates = candidates - - self.best_candidate = best_candidate - - def iter_all(self): - # type: () -> Iterable[InstallationCandidate] - """Iterate through all candidates. - """ - return iter(self._candidates) - - def iter_applicable(self): - # type: () -> Iterable[InstallationCandidate] - """Iterate through the applicable candidates. - """ - return iter(self._applicable_candidates) - - -class CandidateEvaluator(object): - - """ - Responsible for filtering and sorting candidates for installation based - on what tags are valid. - """ - - @classmethod - def create( - cls, - project_name, # type: str - target_python=None, # type: Optional[TargetPython] - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> CandidateEvaluator - """Create a CandidateEvaluator object. - - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - :param hashes: An optional collection of allowed hashes. - """ - if target_python is None: - target_python = TargetPython() - if specifier is None: - specifier = specifiers.SpecifierSet() - - supported_tags = target_python.get_tags() - - return cls( - project_name=project_name, - supported_tags=supported_tags, - specifier=specifier, - prefer_binary=prefer_binary, - allow_all_prereleases=allow_all_prereleases, - hashes=hashes, - ) - - def __init__( - self, - project_name, # type: str - supported_tags, # type: List[Tag] - specifier, # type: specifiers.BaseSpecifier - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> None - """ - :param supported_tags: The PEP 425 tags supported by the target - Python in order of preference (most preferred first). - """ - self._allow_all_prereleases = allow_all_prereleases - self._hashes = hashes - self._prefer_binary = prefer_binary - self._project_name = project_name - self._specifier = specifier - self._supported_tags = supported_tags - - def get_applicable_candidates( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> List[InstallationCandidate] - """ - Return the applicable candidates from a list of candidates. - """ - # Using None infers from the specifier instead. - allow_prereleases = self._allow_all_prereleases or None - specifier = self._specifier - versions = { - str(v) for v in specifier.filter( - # We turn the version object into a str here because otherwise - # when we're debundled but setuptools isn't, Python will see - # packaging.version.Version and - # pkg_resources._vendor.packaging.version.Version as different - # types. This way we'll use a str as a common data interchange - # format. If we stop using the pkg_resources provided specifier - # and start using our own, we can drop the cast to str(). - (str(c.version) for c in candidates), - prereleases=allow_prereleases, - ) - } - - # Again, converting version to str to deal with debundling. - applicable_candidates = [ - c for c in candidates if str(c.version) in versions - ] - - filtered_applicable_candidates = filter_unallowed_hashes( - candidates=applicable_candidates, - hashes=self._hashes, - project_name=self._project_name, - ) - - return sorted(filtered_applicable_candidates, key=self._sort_key) - - def _sort_key(self, candidate): - # type: (InstallationCandidate) -> CandidateSortingKey - """ - Function to pass as the `key` argument to a call to sorted() to sort - InstallationCandidates by preference. - - Returns a tuple such that tuples sorting as greater using Python's - default comparison operator are more preferred. - - The preference is as follows: - - First and foremost, candidates with allowed (matching) hashes are - always preferred over candidates without matching hashes. This is - because e.g. if the only candidate with an allowed hash is yanked, - we still want to use that candidate. - - Second, excepting hash considerations, candidates that have been - yanked (in the sense of PEP 592) are always less preferred than - candidates that haven't been yanked. Then: - - If not finding wheels, they are sorted by version only. - If finding wheels, then the sort order is by version, then: - 1. existing installs - 2. wheels ordered via Wheel.support_index_min(self._supported_tags) - 3. source archives - If prefer_binary was set, then all wheels are sorted above sources. - - Note: it was considered to embed this logic into the Link - comparison operators, but then different sdist links - with the same version, would have to be considered equal - """ - valid_tags = self._supported_tags - support_num = len(valid_tags) - build_tag = () # type: BuildTag - binary_preference = 0 - link = candidate.link - if link.is_wheel: - # can raise InvalidWheelFilename - wheel = Wheel(link.filename) - if not wheel.supported(valid_tags): - raise UnsupportedWheel( - "{} is not a supported wheel for this platform. It " - "can't be sorted.".format(wheel.filename) - ) - if self._prefer_binary: - binary_preference = 1 - pri = -(wheel.support_index_min(valid_tags)) - if wheel.build_tag is not None: - match = re.match(r'^(\d+)(.*)$', wheel.build_tag) - build_tag_groups = match.groups() - build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) - else: # sdist - pri = -(support_num) - has_allowed_hash = int(link.is_hash_allowed(self._hashes)) - yank_value = -1 * int(link.is_yanked) # -1 for yanked. - return ( - has_allowed_hash, yank_value, binary_preference, candidate.version, - build_tag, pri, - ) - - def sort_best_candidate( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> Optional[InstallationCandidate] - """ - Return the best candidate per the instance's sort order, or None if - no candidate is acceptable. - """ - if not candidates: - return None - - best_candidate = max(candidates, key=self._sort_key) - - # Log a warning per PEP 592 if necessary before returning. - link = best_candidate.link - if link.is_yanked: - reason = link.yanked_reason or '' - msg = ( - # Mark this as a unicode string to prevent - # "UnicodeEncodeError: 'ascii' codec can't encode character" - # in Python 2 when the reason contains non-ascii characters. - u'The candidate selected for download or install is a ' - 'yanked version: {candidate}\n' - 'Reason for being yanked: {reason}' - ).format(candidate=best_candidate, reason=reason) - logger.warning(msg) - - return best_candidate - - def compute_best_candidate( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> BestCandidateResult - """ - Compute and return a `BestCandidateResult` instance. - """ - applicable_candidates = self.get_applicable_candidates(candidates) - - best_candidate = self.sort_best_candidate(applicable_candidates) - - return BestCandidateResult( - candidates, - applicable_candidates=applicable_candidates, - best_candidate=best_candidate, - ) - - -class PackageFinder(object): - """This finds packages. - - This is meant to match easy_install's technique for looking for - packages, by reading pages and looking for appropriate links. - """ - - def __init__( - self, - link_collector, # type: LinkCollector - target_python, # type: TargetPython - allow_yanked, # type: bool - format_control=None, # type: Optional[FormatControl] - candidate_prefs=None, # type: CandidatePreferences - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> None - """ - This constructor is primarily meant to be used by the create() class - method and from tests. - - :param format_control: A FormatControl object, used to control - the selection of source packages / binary packages when consulting - the index and links. - :param candidate_prefs: Options to use when creating a - CandidateEvaluator object. - """ - if candidate_prefs is None: - candidate_prefs = CandidatePreferences() - - format_control = format_control or FormatControl(set(), set()) - - self._allow_yanked = allow_yanked - self._candidate_prefs = candidate_prefs - self._ignore_requires_python = ignore_requires_python - self._link_collector = link_collector - self._target_python = target_python - - self.format_control = format_control - - # These are boring links that have already been logged somehow. - self._logged_links = set() # type: Set[Link] - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - @classmethod - def create( - cls, - link_collector, # type: LinkCollector - selection_prefs, # type: SelectionPreferences - target_python=None, # type: Optional[TargetPython] - ): - # type: (...) -> PackageFinder - """Create a PackageFinder. - - :param selection_prefs: The candidate selection preferences, as a - SelectionPreferences object. - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - """ - if target_python is None: - target_python = TargetPython() - - candidate_prefs = CandidatePreferences( - prefer_binary=selection_prefs.prefer_binary, - allow_all_prereleases=selection_prefs.allow_all_prereleases, - ) - - return cls( - candidate_prefs=candidate_prefs, - link_collector=link_collector, - target_python=target_python, - allow_yanked=selection_prefs.allow_yanked, - format_control=selection_prefs.format_control, - ignore_requires_python=selection_prefs.ignore_requires_python, - ) - - @property - def search_scope(self): - # type: () -> SearchScope - return self._link_collector.search_scope - - @search_scope.setter - def search_scope(self, search_scope): - # type: (SearchScope) -> None - self._link_collector.search_scope = search_scope - - @property - def find_links(self): - # type: () -> List[str] - return self._link_collector.find_links - - @property - def index_urls(self): - # type: () -> List[str] - return self.search_scope.index_urls - - @property - def trusted_hosts(self): - # type: () -> Iterable[str] - for host_port in self._link_collector.session.pip_trusted_origins: - yield build_netloc(*host_port) - - @property - def allow_all_prereleases(self): - # type: () -> bool - return self._candidate_prefs.allow_all_prereleases - - def set_allow_all_prereleases(self): - # type: () -> None - self._candidate_prefs.allow_all_prereleases = True - - def make_link_evaluator(self, project_name): - # type: (str) -> LinkEvaluator - canonical_name = canonicalize_name(project_name) - formats = self.format_control.get_allowed_formats(canonical_name) - - return LinkEvaluator( - project_name=project_name, - canonical_name=canonical_name, - formats=formats, - target_python=self._target_python, - allow_yanked=self._allow_yanked, - ignore_requires_python=self._ignore_requires_python, - ) - - def _sort_links(self, links): - # type: (Iterable[Link]) -> List[Link] - """ - Returns elements of links in order, non-egg links first, egg links - second, while eliminating duplicates - """ - eggs, no_eggs = [], [] - seen = set() # type: Set[Link] - for link in links: - if link not in seen: - seen.add(link) - if link.egg_fragment: - eggs.append(link) - else: - no_eggs.append(link) - return no_eggs + eggs - - def _log_skipped_link(self, link, reason): - # type: (Link, Text) -> None - if link not in self._logged_links: - # Mark this as a unicode string to prevent "UnicodeEncodeError: - # 'ascii' codec can't encode character" in Python 2 when - # the reason contains non-ascii characters. - # Also, put the link at the end so the reason is more visible - # and because the link string is usually very long. - logger.debug(u'Skipping link: %s: %s', reason, link) - self._logged_links.add(link) - - def get_install_candidate(self, link_evaluator, link): - # type: (LinkEvaluator, Link) -> Optional[InstallationCandidate] - """ - If the link is a candidate for install, convert it to an - InstallationCandidate and return it. Otherwise, return None. - """ - is_candidate, result = link_evaluator.evaluate_link(link) - if not is_candidate: - if result: - self._log_skipped_link(link, reason=result) - return None - - return InstallationCandidate( - name=link_evaluator.project_name, - link=link, - # Convert the Text result to str since InstallationCandidate - # accepts str. - version=str(result), - ) - - def evaluate_links(self, link_evaluator, links): - # type: (LinkEvaluator, Iterable[Link]) -> List[InstallationCandidate] - """ - Convert links that are candidates to InstallationCandidate objects. - """ - candidates = [] - for link in self._sort_links(links): - candidate = self.get_install_candidate(link_evaluator, link) - if candidate is not None: - candidates.append(candidate) - - return candidates - - def process_project_url(self, project_url, link_evaluator): - # type: (Link, LinkEvaluator) -> List[InstallationCandidate] - logger.debug( - 'Fetching project page and analyzing links: %s', project_url, - ) - html_page = self._link_collector.fetch_page(project_url) - if html_page is None: - return [] - - page_links = list(parse_links(html_page)) - - with indent_log(): - package_links = self.evaluate_links( - link_evaluator, - links=page_links, - ) - - return package_links - - def find_all_candidates(self, project_name): - # type: (str) -> List[InstallationCandidate] - """Find all available InstallationCandidate for project_name - - This checks index_urls and find_links. - All versions found are returned as an InstallationCandidate list. - - See LinkEvaluator.evaluate_link() for details on which files - are accepted. - """ - collected_links = self._link_collector.collect_links(project_name) - - link_evaluator = self.make_link_evaluator(project_name) - - find_links_versions = self.evaluate_links( - link_evaluator, - links=collected_links.find_links, - ) - - page_versions = [] - for project_url in collected_links.project_urls: - package_links = self.process_project_url( - project_url, link_evaluator=link_evaluator, - ) - page_versions.extend(package_links) - - file_versions = self.evaluate_links( - link_evaluator, - links=collected_links.files, - ) - if file_versions: - file_versions.sort(reverse=True) - logger.debug( - 'Local files found: %s', - ', '.join([ - url_to_path(candidate.link.url) - for candidate in file_versions - ]) - ) - - # This is an intentional priority ordering - return file_versions + find_links_versions + page_versions - - def make_candidate_evaluator( - self, - project_name, # type: str - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> CandidateEvaluator - """Create a CandidateEvaluator object to use. - """ - candidate_prefs = self._candidate_prefs - return CandidateEvaluator.create( - project_name=project_name, - target_python=self._target_python, - prefer_binary=candidate_prefs.prefer_binary, - allow_all_prereleases=candidate_prefs.allow_all_prereleases, - specifier=specifier, - hashes=hashes, - ) - - def find_best_candidate( - self, - project_name, # type: str - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> BestCandidateResult - """Find matches for the given project and specifier. - - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - - :return: A `BestCandidateResult` instance. - """ - candidates = self.find_all_candidates(project_name) - candidate_evaluator = self.make_candidate_evaluator( - project_name=project_name, - specifier=specifier, - hashes=hashes, - ) - return candidate_evaluator.compute_best_candidate(candidates) - - def find_requirement(self, req, upgrade): - # type: (InstallRequirement, bool) -> Optional[Link] - """Try to find a Link matching req - - Expects req, an InstallRequirement and upgrade, a boolean - Returns a Link if found, - Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise - """ - hashes = req.hashes(trust_internet=False) - best_candidate_result = self.find_best_candidate( - req.name, specifier=req.specifier, hashes=hashes, - ) - best_candidate = best_candidate_result.best_candidate - - installed_version = None # type: Optional[_BaseVersion] - if req.satisfied_by is not None: - installed_version = parse_version(req.satisfied_by.version) - - def _format_versions(cand_iter): - # type: (Iterable[InstallationCandidate]) -> str - # This repeated parse_version and str() conversion is needed to - # handle different vendoring sources from pip and pkg_resources. - # If we stop using the pkg_resources provided specifier and start - # using our own, we can drop the cast to str(). - return ", ".join(sorted( - {str(c.version) for c in cand_iter}, - key=parse_version, - )) or "none" - - if installed_version is None and best_candidate is None: - logger.critical( - 'Could not find a version that satisfies the requirement %s ' - '(from versions: %s)', - req, - _format_versions(best_candidate_result.iter_all()), - ) - - raise DistributionNotFound( - 'No matching distribution found for {}'.format( - req) - ) - - best_installed = False - if installed_version and ( - best_candidate is None or - best_candidate.version <= installed_version): - best_installed = True - - if not upgrade and installed_version is not None: - if best_installed: - logger.debug( - 'Existing installed version (%s) is most up-to-date and ' - 'satisfies requirement', - installed_version, - ) - else: - logger.debug( - 'Existing installed version (%s) satisfies requirement ' - '(most up-to-date version is %s)', - installed_version, - best_candidate.version, - ) - return None - - if best_installed: - # We have an existing version, and its the best version - logger.debug( - 'Installed version (%s) is most up-to-date (past versions: ' - '%s)', - installed_version, - _format_versions(best_candidate_result.iter_applicable()), - ) - raise BestVersionAlreadyInstalled - - logger.debug( - 'Using version %s (newest of versions: %s)', - best_candidate.version, - _format_versions(best_candidate_result.iter_applicable()), - ) - return best_candidate.link - - -def _find_name_version_sep(fragment, canonical_name): - # type: (str, str) -> int - """Find the separator's index based on the package's canonical name. - - :param fragment: A + filename "fragment" (stem) or - egg fragment. - :param canonical_name: The package's canonical name. - - This function is needed since the canonicalized name does not necessarily - have the same length as the egg info's name part. An example:: - - >>> fragment = 'foo__bar-1.0' - >>> canonical_name = 'foo-bar' - >>> _find_name_version_sep(fragment, canonical_name) - 8 - """ - # Project name and version must be separated by one single dash. Find all - # occurrences of dashes; if the string in front of it matches the canonical - # name, this is the one separating the name and version parts. - for i, c in enumerate(fragment): - if c != "-": - continue - if canonicalize_name(fragment[:i]) == canonical_name: - return i - raise ValueError("{} does not match {}".format(fragment, canonical_name)) - - -def _extract_version_from_fragment(fragment, canonical_name): - # type: (str, str) -> Optional[str] - """Parse the version string from a + filename - "fragment" (stem) or egg fragment. - - :param fragment: The string to parse. E.g. foo-2.1 - :param canonical_name: The canonicalized name of the package this - belongs to. - """ - try: - version_start = _find_name_version_sep(fragment, canonical_name) + 1 - except ValueError: - return None - version = fragment[version_start:] - if not version: - return None - return version diff --git a/env/lib/python3.8/site-packages/pip/_internal/locations.py b/env/lib/python3.8/site-packages/pip/_internal/locations.py deleted file mode 100644 index 5dfcd730..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/locations.py +++ /dev/null @@ -1,200 +0,0 @@ -"""Locations where we look for configs, install stuff, etc""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import os -import os.path -import platform -import site -import sys -import sysconfig -from distutils import sysconfig as distutils_sysconfig -from distutils.command.install import SCHEME_KEYS # type: ignore -from distutils.command.install import install as distutils_install_command - -from pip._internal.models.scheme import Scheme -from pip._internal.utils import appdirs -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast -from pip._internal.utils.virtualenv import running_under_virtualenv - -if MYPY_CHECK_RUNNING: - from typing import Dict, List, Optional, Union - - from distutils.cmd import Command as DistutilsCommand - - -# Application Directories -USER_CACHE_DIR = appdirs.user_cache_dir("pip") - - -def get_major_minor_version(): - # type: () -> str - """ - Return the major-minor version of the current Python as a string, e.g. - "3.7" or "3.10". - """ - return '{}.{}'.format(*sys.version_info) - - -def get_src_prefix(): - # type: () -> str - if running_under_virtualenv(): - src_prefix = os.path.join(sys.prefix, 'src') - else: - # FIXME: keep src in cwd for now (it is not a temporary folder) - try: - src_prefix = os.path.join(os.getcwd(), 'src') - except OSError: - # In case the current working directory has been renamed or deleted - sys.exit( - "The folder you are executing pip from can no longer be found." - ) - - # under macOS + virtualenv sys.prefix is not properly resolved - # it is something like /path/to/python/bin/.. - return os.path.abspath(src_prefix) - - -# FIXME doesn't account for venv linked to global site-packages - -# The python2.7 part of this is Debian specific: -# https://github.com/pypa/pip/issues/5193 -# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths -can_not_depend_on_purelib = ( - sys.version_info[:2] == (2, 7) or - platform.python_implementation().lower() == "pypy" -) -site_packages = None # type: Optional[str] -if can_not_depend_on_purelib: - site_packages = distutils_sysconfig.get_python_lib() -else: - site_packages = sysconfig.get_path("purelib") - -try: - # Use getusersitepackages if this is present, as it ensures that the - # value is initialised properly. - user_site = site.getusersitepackages() -except AttributeError: - user_site = site.USER_SITE - -if WINDOWS: - bin_py = os.path.join(sys.prefix, 'Scripts') - bin_user = os.path.join(user_site, 'Scripts') - # buildout uses 'bin' on Windows too? - if not os.path.exists(bin_py): - bin_py = os.path.join(sys.prefix, 'bin') - bin_user = os.path.join(user_site, 'bin') -else: - bin_py = os.path.join(sys.prefix, 'bin') - bin_user = os.path.join(user_site, 'bin') - - # Forcing to use /usr/local/bin for standard macOS framework installs - # Also log to ~/Library/Logs/ for use with the Console.app log viewer - if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': - bin_py = '/usr/local/bin' - - -def distutils_scheme( - dist_name, user=False, home=None, root=None, isolated=False, prefix=None -): - # type:(str, bool, str, str, bool, str) -> Dict[str, str] - """ - Return a distutils install scheme - """ - from distutils.dist import Distribution - - dist_args = {'name': dist_name} # type: Dict[str, Union[str, List[str]]] - if isolated: - dist_args["script_args"] = ["--no-user-cfg"] - - d = Distribution(dist_args) - d.parse_config_files() - obj = None # type: Optional[DistutilsCommand] - obj = d.get_command_obj('install', create=True) - assert obj is not None - i = cast(distutils_install_command, obj) - # NOTE: setting user or home has the side-effect of creating the home dir - # or user base for installations during finalize_options() - # ideally, we'd prefer a scheme class that has no side-effects. - assert not (user and prefix), "user={} prefix={}".format(user, prefix) - assert not (home and prefix), "home={} prefix={}".format(home, prefix) - i.user = user or i.user - if user or home: - i.prefix = "" - i.prefix = prefix or i.prefix - i.home = home or i.home - i.root = root or i.root - i.finalize_options() - - scheme = {} - for key in SCHEME_KEYS: - scheme[key] = getattr(i, 'install_' + key) - - # install_lib specified in setup.cfg should install *everything* - # into there (i.e. it takes precedence over both purelib and - # platlib). Note, i.install_lib is *always* set after - # finalize_options(); we only want to override here if the user - # has explicitly requested it hence going back to the config - if 'install_lib' in d.get_option_dict('install'): - scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) - - if running_under_virtualenv(): - scheme['headers'] = os.path.join( - sys.prefix, - 'include', - 'site', - 'python{}'.format(get_major_minor_version()), - dist_name, - ) - - if root is not None: - path_no_drive = os.path.splitdrive( - os.path.abspath(scheme["headers"]))[1] - scheme["headers"] = os.path.join( - root, - path_no_drive[1:], - ) - - return scheme - - -def get_scheme( - dist_name, # type: str - user=False, # type: bool - home=None, # type: Optional[str] - root=None, # type: Optional[str] - isolated=False, # type: bool - prefix=None, # type: Optional[str] -): - # type: (...) -> Scheme - """ - Get the "scheme" corresponding to the input parameters. The distutils - documentation provides the context for the available schemes: - https://docs.python.org/3/install/index.html#alternate-installation - - :param dist_name: the name of the package to retrieve the scheme for, used - in the headers scheme path - :param user: indicates to use the "user" scheme - :param home: indicates to use the "home" scheme and provides the base - directory for the same - :param root: root under which other directories are re-based - :param isolated: equivalent to --no-user-cfg, i.e. do not consider - ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for - scheme paths - :param prefix: indicates to use the "prefix" scheme and provides the - base directory for the same - """ - scheme = distutils_scheme( - dist_name, user, home, root, isolated, prefix - ) - return Scheme( - platlib=scheme["platlib"], - purelib=scheme["purelib"], - headers=scheme["headers"], - scripts=scheme["scripts"], - data=scheme["data"], - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/main.py b/env/lib/python3.8/site-packages/pip/_internal/main.py deleted file mode 100644 index 3208d5b8..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/main.py +++ /dev/null @@ -1,16 +0,0 @@ -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, List - - -def main(args=None): - # type: (Optional[List[str]]) -> int - """This is preserved for old console scripts that may still be referencing - it. - - For additional details, see https://github.com/pypa/pip/issues/7498. - """ - from pip._internal.utils.entrypoints import _wrapper - - return _wrapper(args) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/models/__init__.py deleted file mode 100644 index 7855226e..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""A package that contains models that represent entities. -""" diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index af84ad3e9bc5114fed376303adbe6c1e6fecbda2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 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 lX|vO|Yr%lxb`So(vj zt=+q`_8t52VY~fJd%a;6?hm~@OcOsU%m*Sbs&{2N6bYt*(tWy_Aa0{)Z482RC?_3* z(~ij(xyh{q+ObL-J2tOy_keU9Ugb4>E5hY-ynaCTX{XBP`2u(~evY5Vca9sl$x<VtNak(IH1>A8VbJw_ujdCl{+96I0&hcj zVUp#36bas{d1&oGnLTZ4ZlJHBXE!m7aETpPF63mNjOobG)HO{RBRV1sJdEH!AkSzU z{xUP=r6gq=VdBfZVlGXhy<-B)RwklNIS19Uj^P=R3-}zZujFxWr5E;^gG3oDcyqTa zMAZCZu(9{)#$Ke>R#=$iLLwF`amq!Mt&|sLLFtrMZ?A9}guphL9I;Jy5D8fY1IdDOco^WEXNH^ytFY6&E2O?nIh<2m zhcVG->?-D&KEoI;pEW@VykdZggpNXKz#$Bn&^o+)Y=B&bfLv08a^UQdiD2wHxc_;i z5(p?HrcKRlbbaJSOgP1nWSedyyxS(aH8GKgMtfL$I)4A@_@?)C+-TT^Q-+|ZLSf`* z8Dq*ds=^pM6=tfPbkGlRus1{k>8Ck0Vvp2 zk=Im)_pgo2ugTA!jIEKyogG6Cr#kvPcShDe#fouQ8I{`TA>@?aK3BUNmG%*B4nJ=; zleAe@hqvN2o2o#jbgIF|lcGNerO3RGJzs7OVv*#nBYN}5UPbAyK3CBiI;(&*vD$Ep z8Y)`m*>0G3rOKPa&U#Up7j_T{Ulyj%d0~eM7f+S)&FuURe0L`d6dN$K|JJ z1HDFvH)bo~^-5ZT7wXKfS&%+=Vc{k;yr6qXOOdHH*TT;=Xzh|auh(HzaTV`Pi#-+zPi3ooLh-`326-4| zWffi464Mu{g<=r8c(bwwugos%jjepI2Q5p{(xgu*ZBsG*|S>BhDQa&5@#Zcws_Ftj*eKHaNSB?UW|U ztrb1-4(YM4!DIN!iC5qPVt@#}Z`*hlDxbv75o&@0&L z85o8b7HEu9g3%FTgn3tpdEC47QlIQ~)N#zSrqG?Pohft!wonNvv|cN}eUNeJh;;I`yzBhn3Qt z*+h(;WV8MC3C)#;zt+bdTL0kxXHVj0`Us@!(Q|nGmF%hFqBpM2;ToU-9-FlMEXfV3 w{)p##`8560>FKcv-$QAOHfD2E+SyF_a!J)8wgcV+)A6?V2_}gA4!q^}59&uOod5s; diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc deleted file mode 100644 index 029db938702145d4e16fda05cc5baef37a7c6ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7088 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc deleted file mode 100644 index 6b77dff585e0159ea3242c11a9613fe3e2284eec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3386 zcmb7GOK%*<5uTpc&JLH9MA4FL=P;oiM+-h-q z@BcddfYrDZ`|-`@l(}n7?aHCK%E1n6>QweAW5&Lx++#y3)tY*hSy`thbi6mQReS2wj)_~jyK{-T zXNq;zna(E`y@mJG{(5CpR%IskUrZd@8UIF`NoTz;IF1=a!HgS%a%-2zDu}if7r|NF z(qczD?$N5WAnM~xTeYQ`)0g21A<b?~)znX{X{RzzK~}xP*qs-D*K2mOmNE!Z<6R1TtSm~3xXh| z*KYGQu|$HsTc(A^U)L4iqZtRD;j+Ho6dss#kuF4+HY~orf`oC&@o)Z*qkRl5vWLzv zZE$Oe`KD+2E#e$84P3K3rpLVJuH|B8f!WVJ%#Gjq7H*3vf@jZJG<8G+%znkTS;7+Y z#QU@Hm4UI9*e4#5fxxJ9{y#tAY9w?Go2_Wu<)}!4gERsVv+dr6PyCA-G2roDQwiY= zUF-v-W6IMx@?>y(I~7t9E_Ja)YV9@%4Wc4B*D?aC)c`sCTnDNqV4jR(z&y(?>cjaf zuOXOVc^ysOL8pu<(vLEyma@NYC}&O>DCtl|mA5N+P=Y*1kVWVnHJU@BEbef*h3wvg}9frdxJl<;~;)=>c< z2$-z%jqOp|9k0F`;tNM#Mva%1zUBvFiS`3QeTTT*nXs=lm;Y+++u$)(lcxJVMqu>n z`NT3twZEFtjjGItYk!2SDeNM-kAM3A8G4}x-=LZYw-MXKCTFrmM#C-k>(5q&N@ ze~Il)E$})E<9EM}B^%u~)e^dZhGFf8VRLK1xD$r^qbPf^(h9?*j4?eIXOWaS$BiNp z?~svHAjOZUTchs6b9zJ;3%b3(fhIfXJkz#K=HK?(-m+flzA0$2Zqa=J8CqO}Bz{6u zZ=+oI!UJHc6g?{F5pC#=REm27;jRCj*&TppFE0;X!+dI%zTgVDG2zO%xQT~zoR zx;9Dkl@0n6JqmE7nhVaYmo+pS@>It9dZZI=eW?-!Y~xf^b!+#9&?cdcK(6aMkoW}| qN~ySZo7n!XX+NOs91&H(#16>(t&_fnMkiuOjK~dF6uxR58L5uV*yA-LA zR9pw{DMkOKztPXoHK+bUP8~|#wS_JXjYW=T=FNK~&qt$U1moAg{-OQ|p^ss5I1-pV zgU3Aq!x6^{6?lO$64*Y3d8DEuUc@-~VwDuVMGvFrh$p=FC*nQP{}3;Zc>gsTAN>m% z&=}XB{q$!3hE89cO@E}X&a>=g_8e9RKbKw_%@n+kX2urGPmT80s650SjvGw(VO5|7 z=4cUdyohV^#`v=cX(LN>D^^Rqem?(w%{!mJ>r zu!Zyw*B;nb9I8=dP`=3+O-!vhBqJ zfX-Al2WTw6Vi%z6ge;|IcC%kuUkXhi7bx$qRSf9D2=&HZGy_IplPC&+$4X4DyHH7RSm^;CQ`{{3F zhw%65#l#ooq?F}JrGv(TpMai1ojk6Vn@7uy3cd-I+6xO;$)qq`C^xy;A_42lrRAm` zQ20uEN2=gNnPsyKSb;p66@t?Gm{KTLsqj9e^lin| z&T~X5H#wy?lxZ3{Fr%>60~0!Sq02#(3=wXApBhg#9@O`tvGk^~wDMB9)Ne}I!ZzG1 yb$>UB!{qDk*DVccR~s9y(YoJW8cm%8Q~`$#(CWdHwyUQYW-fpnMhPC`Vf-JfF3Ye0 diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc deleted file mode 100644 index df538e741b6d0216070025d7ae7ca1aa89078678..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3249 zcma)8-HzMF73K^niL2GxZW}vx+8R@!h^=<{vLB4IwB^xn@^m6qxPoXlpKDvtIlDh;liVtndI5&XKjJ&K{kwva+*X&mBLJvD0E&Z zZDM@pBN2&uw1_jKbfFcb$TKBkjJDe1Y-|;ca*feNG(3*R=*~(LCCR>!`Qt3fBe^e> z83uM_Z`j!Ir-^n8&wV`Q2x89XP6#R4v9GTic7&GX|KQi01DaV3q8qN`Sc51IcZx_ysVEQ#c#_@` zzZ0d=a8AIl9y|`jyCd7!7p02yaDo7l&r6TXl_t_=CXo@5R$_$~F__u#4yRhH%!qPU z8kGj(J;Yo;j!U&K9>+-{MsX&$RGsUubq=FU43rp5&OsRB}Ca35{qFzYG;tDfBLb z537cGTEN6XoWy1pnrK`G#q7p5K(?6VW><`++0c3wmDpO}SUXM;u@o_~u74*pw!-)= zCW-HAM(-K+ic_)R8OOW3S6vCm@rla9Vmr^3i#$}F%|vM8tI9jdZH1h}V~I zADFZ_DB|MQG@~u0ze&tIuO^t$rOtVfFRD^94!^N{WN{qp&=M4|Dzn-|&L> zPFtTZe*5`P^a2ICSzFR|^>wJI++#JX8bIe%z2KM@=>IdGlIooYnE21T4SfM0`g9uc-=~kpD2V}HG={sl;8f|g@Jz9iVR+nm^mkKneye~KvYQiKQLM+Z8|MC{DEzed1 z5aFKwdxgpOm6__go~>)Fmu91M^txWvT2k6NPnAdP z)otl(2uYnt!jz`%upVWJsO#Bm*7S4}{gp=^y_i6s*qAy##E?39t+q=k1Ho|4IP>WK zy4h^<7wF}DX4mWC>b8icvM5zyShd3tTsBRp-3h}_r%|%(X@#N8hheCHOeWtT@pBTy zmm7lirKW>9ZK#rj&%GA*HQiseyZ#m1+r6Z5W_POB!K1;7M*|!sk}~*a{i)+b5v#7g zY(^TF!@6|5_Ofm>D{x%U#GX}i`9UDnbd=OS{jTSsNXc9W^(hKd0vq`qJ1-v`siCpf gZ}@B7w`Ansts{4jNV}xH>hnuphjqBeUf~`0|ImtK0{{R3 diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 95403333204676cb43763002684926d4ebed3b28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3192 zcmbVO-E-SS5Z6hvEjv#7L579`9d!n#acPu53sXYIDYWUw03nlp(3-YF@ttj@vZUO} z`7q84$v~fAhQAbiKjy(>iq6QL6q1R?G@e;e`tuwpLywDGuPU$bOU0bXW zY25Le@EX4ru6uz`zeZKpK@%PX`pGXJEIn|q-dwo)xx0LKaq-sT4WOD|_#&yJh{0dx zm?}`21`g3`IwduOnR_{^Gjlb+uh$CHpysYtvuKXy;ayA}P%F_QEx~$(j(`iwGN(-G zmOmZ1e)s3clk-b+XxlpD)&9KdyfLVIPem+%0xYMHd;aNp+n*FQ-0WpD(}?w0S6c`M<3u@{0hTUZB^SN zJ+e=>^`0)yB;bub1J^s`d!RqnT(hU6Z}!Pv9{sYf1FfKFxgnaRX!(6SQ&jT;@JrNE zlo3TK4p7R9QW~I){-`ww9iio23+x)XrtP4tF**v~9_!xEZaK?6UjVp{0>muFB2;KY zG%9fU!uC__*o}zy(VB_tp8amyhCN}F08e3TAfPD0ktV(*ai5bZX+T6|PK8V6RD2|H zqyeFkCWfR=z_I-wdfS5MHF(4f3@xpvJ(}Exo2_csv`24kgFjaZ%#LpxiQXeUy=Uwg zznE(iYh!EXZS9#>F{BB?1t#rv^XM9<{=EQ zlvY1PGS}o$Czb`y;Er|13%IQSjuw6t%A#_%n|Mu`6LH`tvZVZuOuK=K(Rmr_eGAC!amDP+BYEUSMBTnXH*<;ujw+rBW3JQ+8}Ntv9)zfmIQi|*L) z-G^e0amV{zg-49Tkf_4D3lYZ%??6rgl8x@AWtMb!3Q}d-IjE3ewC!Oj6%kJuwF5|D zERiDNP!5GNqzNH_ngl+t!vL5X+a`(D10DA?qOIvv1MCo0KS9JZog)IJ0eVs&AW~8v z6z7^OWScRseuUx>u_lDNJCk0u$r3k>7nqfX6OA2+djEJum-*Cs{w_*aZdQ5@m7RKp zxQnP-l`5nA_J1lKDrk5jD`*(;L{mis`rWQI>~`-Dh|hrMgJ^?+i~W$Y&9whSAv=Y1 z3%0MiAcwvQ&t+Q-9a7D7z$`RJK_!y~b*tfXbq{3%D!+iU(B>)1W}HLKv(S0HwvsTb zwl6I#*_S@}Fohp<>3WORpD2z3rtLL7KSYUe!-!MHGsW1vHvFVzwQSl{!44qM None - self.name = name - self.version = parse_version(version) # type: _BaseVersion - self.link = link - - super(InstallationCandidate, self).__init__( - key=(self.name, self.version, self.link), - defining_class=InstallationCandidate - ) - - def __repr__(self): - # type: () -> str - return "".format( - self.name, self.version, self.link, - ) - - def __str__(self): - # type: () -> str - return '{!r} candidate (version {} at {})'.format( - self.name, self.version, self.link, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/direct_url.py b/env/lib/python3.8/site-packages/pip/_internal/models/direct_url.py deleted file mode 100644 index 87bd9fe4..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/direct_url.py +++ /dev/null @@ -1,245 +0,0 @@ -""" PEP 610 """ -import json -import re - -from pip._vendor import six -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Dict, Iterable, Optional, Type, TypeVar, Union - ) - - T = TypeVar("T") - - -DIRECT_URL_METADATA_NAME = "direct_url.json" -ENV_VAR_RE = re.compile(r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$") - -__all__ = [ - "DirectUrl", - "DirectUrlValidationError", - "DirInfo", - "ArchiveInfo", - "VcsInfo", -] - - -class DirectUrlValidationError(Exception): - pass - - -def _get(d, expected_type, key, default=None): - # type: (Dict[str, Any], Type[T], str, Optional[T]) -> Optional[T] - """Get value from dictionary and verify expected type.""" - if key not in d: - return default - value = d[key] - if six.PY2 and expected_type is str: - expected_type = six.string_types # type: ignore - if not isinstance(value, expected_type): - raise DirectUrlValidationError( - "{!r} has unexpected type for {} (expected {})".format( - value, key, expected_type - ) - ) - return value - - -def _get_required(d, expected_type, key, default=None): - # type: (Dict[str, Any], Type[T], str, Optional[T]) -> T - value = _get(d, expected_type, key, default) - if value is None: - raise DirectUrlValidationError("{} must have a value".format(key)) - return value - - -def _exactly_one_of(infos): - # type: (Iterable[Optional[InfoType]]) -> InfoType - infos = [info for info in infos if info is not None] - if not infos: - raise DirectUrlValidationError( - "missing one of archive_info, dir_info, vcs_info" - ) - if len(infos) > 1: - raise DirectUrlValidationError( - "more than one of archive_info, dir_info, vcs_info" - ) - assert infos[0] is not None - return infos[0] - - -def _filter_none(**kwargs): - # type: (Any) -> Dict[str, Any] - """Make dict excluding None values.""" - return {k: v for k, v in kwargs.items() if v is not None} - - -class VcsInfo(object): - name = "vcs_info" - - def __init__( - self, - vcs, # type: str - commit_id, # type: str - requested_revision=None, # type: Optional[str] - resolved_revision=None, # type: Optional[str] - resolved_revision_type=None, # type: Optional[str] - ): - self.vcs = vcs - self.requested_revision = requested_revision - self.commit_id = commit_id - self.resolved_revision = resolved_revision - self.resolved_revision_type = resolved_revision_type - - @classmethod - def _from_dict(cls, d): - # type: (Optional[Dict[str, Any]]) -> Optional[VcsInfo] - if d is None: - return None - return cls( - vcs=_get_required(d, str, "vcs"), - commit_id=_get_required(d, str, "commit_id"), - requested_revision=_get(d, str, "requested_revision"), - resolved_revision=_get(d, str, "resolved_revision"), - resolved_revision_type=_get(d, str, "resolved_revision_type"), - ) - - def _to_dict(self): - # type: () -> Dict[str, Any] - return _filter_none( - vcs=self.vcs, - requested_revision=self.requested_revision, - commit_id=self.commit_id, - resolved_revision=self.resolved_revision, - resolved_revision_type=self.resolved_revision_type, - ) - - -class ArchiveInfo(object): - name = "archive_info" - - def __init__( - self, - hash=None, # type: Optional[str] - ): - self.hash = hash - - @classmethod - def _from_dict(cls, d): - # type: (Optional[Dict[str, Any]]) -> Optional[ArchiveInfo] - if d is None: - return None - return cls(hash=_get(d, str, "hash")) - - def _to_dict(self): - # type: () -> Dict[str, Any] - return _filter_none(hash=self.hash) - - -class DirInfo(object): - name = "dir_info" - - def __init__( - self, - editable=False, # type: bool - ): - self.editable = editable - - @classmethod - def _from_dict(cls, d): - # type: (Optional[Dict[str, Any]]) -> Optional[DirInfo] - if d is None: - return None - return cls( - editable=_get_required(d, bool, "editable", default=False) - ) - - def _to_dict(self): - # type: () -> Dict[str, Any] - return _filter_none(editable=self.editable or None) - - -if MYPY_CHECK_RUNNING: - InfoType = Union[ArchiveInfo, DirInfo, VcsInfo] - - -class DirectUrl(object): - - def __init__( - self, - url, # type: str - info, # type: InfoType - subdirectory=None, # type: Optional[str] - ): - self.url = url - self.info = info - self.subdirectory = subdirectory - - def _remove_auth_from_netloc(self, netloc): - # type: (str) -> str - if "@" not in netloc: - return netloc - user_pass, netloc_no_user_pass = netloc.split("@", 1) - if ( - isinstance(self.info, VcsInfo) and - self.info.vcs == "git" and - user_pass == "git" - ): - return netloc - if ENV_VAR_RE.match(user_pass): - return netloc - return netloc_no_user_pass - - @property - def redacted_url(self): - # type: () -> str - """url with user:password part removed unless it is formed with - environment variables as specified in PEP 610, or it is ``git`` - in the case of a git URL. - """ - purl = urllib_parse.urlsplit(self.url) - netloc = self._remove_auth_from_netloc(purl.netloc) - surl = urllib_parse.urlunsplit( - (purl.scheme, netloc, purl.path, purl.query, purl.fragment) - ) - return surl - - def validate(self): - # type: () -> None - self.from_dict(self.to_dict()) - - @classmethod - def from_dict(cls, d): - # type: (Dict[str, Any]) -> DirectUrl - return DirectUrl( - url=_get_required(d, str, "url"), - subdirectory=_get(d, str, "subdirectory"), - info=_exactly_one_of( - [ - ArchiveInfo._from_dict(_get(d, dict, "archive_info")), - DirInfo._from_dict(_get(d, dict, "dir_info")), - VcsInfo._from_dict(_get(d, dict, "vcs_info")), - ] - ), - ) - - def to_dict(self): - # type: () -> Dict[str, Any] - res = _filter_none( - url=self.redacted_url, - subdirectory=self.subdirectory, - ) - res[self.info.name] = self.info._to_dict() - return res - - @classmethod - def from_json(cls, s): - # type: (str) -> DirectUrl - return cls.from_dict(json.loads(s)) - - def to_json(self): - # type: () -> str - return json.dumps(self.to_dict(), sort_keys=True) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/format_control.py b/env/lib/python3.8/site-packages/pip/_internal/models/format_control.py deleted file mode 100644 index 2e13727c..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/format_control.py +++ /dev/null @@ -1,84 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import CommandError -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Set, FrozenSet - - -class FormatControl(object): - """Helper for managing formats from which a package can be installed. - """ - - def __init__(self, no_binary=None, only_binary=None): - # type: (Optional[Set[str]], Optional[Set[str]]) -> None - if no_binary is None: - no_binary = set() - if only_binary is None: - only_binary = set() - - self.no_binary = no_binary - self.only_binary = only_binary - - def __eq__(self, other): - # type: (object) -> bool - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - # type: (object) -> bool - return not self.__eq__(other) - - def __repr__(self): - # type: () -> str - return "{}({}, {})".format( - self.__class__.__name__, - self.no_binary, - self.only_binary - ) - - @staticmethod - def handle_mutual_excludes(value, target, other): - # type: (str, Optional[Set[str]], Optional[Set[str]]) -> None - if value.startswith('-'): - raise CommandError( - "--no-binary / --only-binary option requires 1 argument." - ) - new = value.split(',') - while ':all:' in new: - other.clear() - target.clear() - target.add(':all:') - del new[:new.index(':all:') + 1] - # Without a none, we want to discard everything as :all: covers it - if ':none:' not in new: - return - for name in new: - if name == ':none:': - target.clear() - continue - name = canonicalize_name(name) - other.discard(name) - target.add(name) - - def get_allowed_formats(self, canonical_name): - # type: (str) -> FrozenSet[str] - result = {"binary", "source"} - if canonical_name in self.only_binary: - result.discard('source') - elif canonical_name in self.no_binary: - result.discard('binary') - elif ':all:' in self.only_binary: - result.discard('source') - elif ':all:' in self.no_binary: - result.discard('binary') - return frozenset(result) - - def disallow_binaries(self): - # type: () -> None - self.handle_mutual_excludes( - ':all:', self.no_binary, self.only_binary, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/index.py b/env/lib/python3.8/site-packages/pip/_internal/models/index.py deleted file mode 100644 index ead1efbd..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/index.py +++ /dev/null @@ -1,31 +0,0 @@ -from pip._vendor.six.moves.urllib import parse as urllib_parse - - -class PackageIndex(object): - """Represents a Package Index and provides easier access to endpoints - """ - - def __init__(self, url, file_storage_domain): - # type: (str, str) -> None - super(PackageIndex, self).__init__() - self.url = url - self.netloc = urllib_parse.urlsplit(url).netloc - self.simple_url = self._url_for_path('simple') - self.pypi_url = self._url_for_path('pypi') - - # This is part of a temporary hack used to block installs of PyPI - # packages which depend on external urls only necessary until PyPI can - # block such packages themselves - self.file_storage_domain = file_storage_domain - - def _url_for_path(self, path): - # type: (str) -> str - return urllib_parse.urljoin(self.url, path) - - -PyPI = PackageIndex( - 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' -) -TestPyPI = PackageIndex( - 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' -) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/link.py b/env/lib/python3.8/site-packages/pip/_internal/models/link.py deleted file mode 100644 index df4f8f01..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/link.py +++ /dev/null @@ -1,236 +0,0 @@ -import os -import posixpath -import re - -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.utils.filetypes import WHEEL_EXTENSION -from pip._internal.utils.misc import ( - redact_auth_from_url, - split_auth_from_netloc, - splitext, -) -from pip._internal.utils.models import KeyBasedCompareMixin -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url, url_to_path - -if MYPY_CHECK_RUNNING: - from typing import Optional, Text, Tuple, Union - from pip._internal.index.collector import HTMLPage - from pip._internal.utils.hashes import Hashes - - -class Link(KeyBasedCompareMixin): - """Represents a parsed link from a Package Index's simple URL - """ - - def __init__( - self, - url, # type: str - comes_from=None, # type: Optional[Union[str, HTMLPage]] - requires_python=None, # type: Optional[str] - yanked_reason=None, # type: Optional[Text] - cache_link_parsing=True, # type: bool - ): - # type: (...) -> None - """ - :param url: url of the resource pointed to (href of the link) - :param comes_from: instance of HTMLPage where the link was found, - or string. - :param requires_python: String containing the `Requires-Python` - metadata field, specified in PEP 345. This may be specified by - a data-requires-python attribute in the HTML link tag, as - described in PEP 503. - :param yanked_reason: the reason the file has been yanked, if the - file has been yanked, or None if the file hasn't been yanked. - This is the value of the "data-yanked" attribute, if present, in - a simple repository HTML link. If the file has been yanked but - no reason was provided, this should be the empty string. See - PEP 592 for more information and the specification. - :param cache_link_parsing: A flag that is used elsewhere to determine - whether resources retrieved from this link - should be cached. PyPI index urls should - generally have this set to False, for - example. - """ - - # url can be a UNC windows share - if url.startswith('\\\\'): - url = path_to_url(url) - - self._parsed_url = urllib_parse.urlsplit(url) - # Store the url as a private attribute to prevent accidentally - # trying to set a new value. - self._url = url - - self.comes_from = comes_from - self.requires_python = requires_python if requires_python else None - self.yanked_reason = yanked_reason - - super(Link, self).__init__(key=url, defining_class=Link) - - self.cache_link_parsing = cache_link_parsing - - def __str__(self): - # type: () -> str - if self.requires_python: - rp = ' (requires-python:{})'.format(self.requires_python) - else: - rp = '' - if self.comes_from: - return '{} (from {}){}'.format( - redact_auth_from_url(self._url), self.comes_from, rp) - else: - return redact_auth_from_url(str(self._url)) - - def __repr__(self): - # type: () -> str - return ''.format(self) - - @property - def url(self): - # type: () -> str - return self._url - - @property - def filename(self): - # type: () -> str - path = self.path.rstrip('/') - name = posixpath.basename(path) - if not name: - # Make sure we don't leak auth information if the netloc - # includes a username and password. - netloc, user_pass = split_auth_from_netloc(self.netloc) - return netloc - - name = urllib_parse.unquote(name) - assert name, ( - 'URL {self._url!r} produced no filename'.format(**locals())) - return name - - @property - def file_path(self): - # type: () -> str - return url_to_path(self.url) - - @property - def scheme(self): - # type: () -> str - return self._parsed_url.scheme - - @property - def netloc(self): - # type: () -> str - """ - This can contain auth information. - """ - return self._parsed_url.netloc - - @property - def path(self): - # type: () -> str - return urllib_parse.unquote(self._parsed_url.path) - - def splitext(self): - # type: () -> Tuple[str, str] - return splitext(posixpath.basename(self.path.rstrip('/'))) - - @property - def ext(self): - # type: () -> str - return self.splitext()[1] - - @property - def url_without_fragment(self): - # type: () -> str - scheme, netloc, path, query, fragment = self._parsed_url - return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) - - _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') - - @property - def egg_fragment(self): - # type: () -> Optional[str] - match = self._egg_fragment_re.search(self._url) - if not match: - return None - return match.group(1) - - _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') - - @property - def subdirectory_fragment(self): - # type: () -> Optional[str] - match = self._subdirectory_fragment_re.search(self._url) - if not match: - return None - return match.group(1) - - _hash_re = re.compile( - r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' - ) - - @property - def hash(self): - # type: () -> Optional[str] - match = self._hash_re.search(self._url) - if match: - return match.group(2) - return None - - @property - def hash_name(self): - # type: () -> Optional[str] - match = self._hash_re.search(self._url) - if match: - return match.group(1) - return None - - @property - def show_url(self): - # type: () -> str - return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0]) - - @property - def is_file(self): - # type: () -> bool - return self.scheme == 'file' - - def is_existing_dir(self): - # type: () -> bool - return self.is_file and os.path.isdir(self.file_path) - - @property - def is_wheel(self): - # type: () -> bool - return self.ext == WHEEL_EXTENSION - - @property - def is_vcs(self): - # type: () -> bool - from pip._internal.vcs import vcs - - return self.scheme in vcs.all_schemes - - @property - def is_yanked(self): - # type: () -> bool - return self.yanked_reason is not None - - @property - def has_hash(self): - # type: () -> bool - return self.hash_name is not None - - def is_hash_allowed(self, hashes): - # type: (Optional[Hashes]) -> bool - """ - Return True if the link has a hash and it is allowed. - """ - if hashes is None or not self.has_hash: - return False - # Assert non-None so mypy knows self.hash_name and self.hash are str. - assert self.hash_name is not None - assert self.hash is not None - - return hashes.is_hash_allowed(self.hash_name, hex_digest=self.hash) diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/scheme.py b/env/lib/python3.8/site-packages/pip/_internal/models/scheme.py deleted file mode 100644 index af07b407..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/scheme.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -For types associated with installation schemes. - -For a general overview of available schemes and their context, see -https://docs.python.org/3/install/index.html#alternate-installation. -""" - - -class Scheme(object): - """A Scheme holds paths which are used as the base directories for - artifacts associated with a Python package. - """ - def __init__( - self, - platlib, # type: str - purelib, # type: str - headers, # type: str - scripts, # type: str - data, # type: str - ): - self.platlib = platlib - self.purelib = purelib - self.headers = headers - self.scripts = scripts - self.data = data diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/search_scope.py b/env/lib/python3.8/site-packages/pip/_internal/models/search_scope.py deleted file mode 100644 index 7a0008e4..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/search_scope.py +++ /dev/null @@ -1,133 +0,0 @@ -import itertools -import logging -import os -import posixpath - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.models.index import PyPI -from pip._internal.utils.compat import has_tls -from pip._internal.utils.misc import normalize_path, redact_auth_from_url -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List - - -logger = logging.getLogger(__name__) - - -class SearchScope(object): - - """ - Encapsulates the locations that pip is configured to search. - """ - - @classmethod - def create( - cls, - find_links, # type: List[str] - index_urls, # type: List[str] - ): - # type: (...) -> SearchScope - """ - Create a SearchScope object after normalizing the `find_links`. - """ - # Build find_links. If an argument starts with ~, it may be - # a local file relative to a home directory. So try normalizing - # it and if it exists, use the normalized version. - # This is deliberately conservative - it might be fine just to - # blindly normalize anything starting with a ~... - built_find_links = [] # type: List[str] - for link in find_links: - if link.startswith('~'): - new_link = normalize_path(link) - if os.path.exists(new_link): - link = new_link - built_find_links.append(link) - - # If we don't have TLS enabled, then WARN if anyplace we're looking - # relies on TLS. - if not has_tls(): - for link in itertools.chain(index_urls, built_find_links): - parsed = urllib_parse.urlparse(link) - if parsed.scheme == 'https': - logger.warning( - 'pip is configured with locations that require ' - 'TLS/SSL, however the ssl module in Python is not ' - 'available.' - ) - break - - return cls( - find_links=built_find_links, - index_urls=index_urls, - ) - - def __init__( - self, - find_links, # type: List[str] - index_urls, # type: List[str] - ): - # type: (...) -> None - self.find_links = find_links - self.index_urls = index_urls - - def get_formatted_locations(self): - # type: () -> str - lines = [] - redacted_index_urls = [] - if self.index_urls and self.index_urls != [PyPI.simple_url]: - for url in self.index_urls: - - redacted_index_url = redact_auth_from_url(url) - - # Parse the URL - purl = urllib_parse.urlsplit(redacted_index_url) - - # URL is generally invalid if scheme and netloc is missing - # there are issues with Python and URL parsing, so this test - # is a bit crude. See bpo-20271, bpo-23505. Python doesn't - # always parse invalid URLs correctly - it should raise - # exceptions for malformed URLs - if not purl.scheme and not purl.netloc: - logger.warning( - 'The index url "{}" seems invalid, ' - 'please provide a scheme.'.format(redacted_index_url)) - - redacted_index_urls.append(redacted_index_url) - - lines.append('Looking in indexes: {}'.format( - ', '.join(redacted_index_urls))) - - if self.find_links: - lines.append( - 'Looking in links: {}'.format(', '.join( - redact_auth_from_url(url) for url in self.find_links)) - ) - return '\n'.join(lines) - - def get_index_urls_locations(self, project_name): - # type: (str) -> List[str] - """Returns the locations found via self.index_urls - - Checks the url_name on the main (first in the list) index and - use this url_name to produce all locations - """ - - def mkurl_pypi_url(url): - # type: (str) -> str - loc = posixpath.join( - url, - urllib_parse.quote(canonicalize_name(project_name))) - # For maximum compatibility with easy_install, ensure the path - # ends in a trailing slash. Although this isn't in the spec - # (and PyPI can handle it without the slash) some other index - # implementations might break if they relied on easy_install's - # behavior. - if not loc.endswith('/'): - loc = loc + '/' - return loc - - return [mkurl_pypi_url(url) for url in self.index_urls] diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py b/env/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py deleted file mode 100644 index f58fdce9..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py +++ /dev/null @@ -1,47 +0,0 @@ -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional - from pip._internal.models.format_control import FormatControl - - -class SelectionPreferences(object): - - """ - Encapsulates the candidate selection preferences for downloading - and installing files. - """ - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - def __init__( - self, - allow_yanked, # type: bool - allow_all_prereleases=False, # type: bool - format_control=None, # type: Optional[FormatControl] - prefer_binary=False, # type: bool - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> None - """Create a SelectionPreferences object. - - :param allow_yanked: Whether files marked as yanked (in the sense - of PEP 592) are permitted to be candidates for install. - :param format_control: A FormatControl object or None. Used to control - the selection of source packages / binary packages when consulting - the index and links. - :param prefer_binary: Whether to prefer an old, but valid, binary - dist over a new source dist. - :param ignore_requires_python: Whether to ignore incompatible - "Requires-Python" values in links. Defaults to False. - """ - if ignore_requires_python is None: - ignore_requires_python = False - - self.allow_yanked = allow_yanked - self.allow_all_prereleases = allow_all_prereleases - self.format_control = format_control - self.prefer_binary = prefer_binary - self.ignore_requires_python = ignore_requires_python diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/target_python.py b/env/lib/python3.8/site-packages/pip/_internal/models/target_python.py deleted file mode 100644 index 84f1c209..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/target_python.py +++ /dev/null @@ -1,110 +0,0 @@ -import sys - -from pip._internal.utils.compatibility_tags import ( - get_supported, - version_info_to_nodot, -) -from pip._internal.utils.misc import normalize_version_info -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Tuple - - from pip._vendor.packaging.tags import Tag - - -class TargetPython(object): - - """ - Encapsulates the properties of a Python interpreter one is targeting - for a package install, download, etc. - """ - - def __init__( - self, - platform=None, # type: Optional[str] - py_version_info=None, # type: Optional[Tuple[int, ...]] - abi=None, # type: Optional[str] - implementation=None, # type: Optional[str] - ): - # type: (...) -> None - """ - :param platform: A string or None. If None, searches for packages - that are supported by the current system. Otherwise, will find - packages that can be built on the platform passed in. These - packages will only be downloaded for distribution: they will - not be built locally. - :param py_version_info: An optional tuple of ints representing the - Python version information to use (e.g. `sys.version_info[:3]`). - This can have length 1, 2, or 3 when provided. - :param abi: A string or None. This is passed to compatibility_tags.py's - get_supported() function as is. - :param implementation: A string or None. This is passed to - compatibility_tags.py's get_supported() function as is. - """ - # Store the given py_version_info for when we call get_supported(). - self._given_py_version_info = py_version_info - - if py_version_info is None: - py_version_info = sys.version_info[:3] - else: - py_version_info = normalize_version_info(py_version_info) - - py_version = '.'.join(map(str, py_version_info[:2])) - - self.abi = abi - self.implementation = implementation - self.platform = platform - self.py_version = py_version - self.py_version_info = py_version_info - - # This is used to cache the return value of get_tags(). - self._valid_tags = None # type: Optional[List[Tag]] - - def format_given(self): - # type: () -> str - """ - Format the given, non-None attributes for display. - """ - display_version = None - if self._given_py_version_info is not None: - display_version = '.'.join( - str(part) for part in self._given_py_version_info - ) - - key_values = [ - ('platform', self.platform), - ('version_info', display_version), - ('abi', self.abi), - ('implementation', self.implementation), - ] - return ' '.join( - '{}={!r}'.format(key, value) for key, value in key_values - if value is not None - ) - - def get_tags(self): - # type: () -> List[Tag] - """ - Return the supported PEP 425 tags to check wheel candidates against. - - The tags are returned in order of preference (most preferred first). - """ - if self._valid_tags is None: - # Pass versions=None if no py_version_info was given since - # versions=None uses special default logic. - py_version_info = self._given_py_version_info - if py_version_info is None: - version = None - else: - version = version_info_to_nodot(py_version_info) - - tags = get_supported( - version=version, - platform=self.platform, - abi=self.abi, - impl=self.implementation, - ) - self._valid_tags = tags - - return self._valid_tags diff --git a/env/lib/python3.8/site-packages/pip/_internal/models/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/models/wheel.py deleted file mode 100644 index 4d4068f3..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/models/wheel.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Represents a wheel file and provides access to the various parts of the -name that have meaning. -""" -import re - -from pip._vendor.packaging.tags import Tag - -from pip._internal.exceptions import InvalidWheelFilename -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List - - -class Wheel(object): - """A wheel file""" - - wheel_file_re = re.compile( - r"""^(?P(?P.+?)-(?P.*?)) - ((-(?P\d[^-]*?))?-(?P.+?)-(?P.+?)-(?P.+?) - \.whl|\.dist-info)$""", - re.VERBOSE - ) - - def __init__(self, filename): - # type: (str) -> None - """ - :raises InvalidWheelFilename: when the filename is invalid for a wheel - """ - wheel_info = self.wheel_file_re.match(filename) - if not wheel_info: - raise InvalidWheelFilename( - "{} is not a valid wheel filename.".format(filename) - ) - self.filename = filename - self.name = wheel_info.group('name').replace('_', '-') - # we'll assume "_" means "-" due to wheel naming scheme - # (https://github.com/pypa/pip/issues/1150) - self.version = wheel_info.group('ver').replace('_', '-') - self.build_tag = wheel_info.group('build') - self.pyversions = wheel_info.group('pyver').split('.') - self.abis = wheel_info.group('abi').split('.') - self.plats = wheel_info.group('plat').split('.') - - # All the tag combinations from this file - self.file_tags = { - Tag(x, y, z) for x in self.pyversions - for y in self.abis for z in self.plats - } - - def get_formatted_file_tags(self): - # type: () -> List[str] - """Return the wheel's tags as a sorted list of strings.""" - return sorted(str(tag) for tag in self.file_tags) - - def support_index_min(self, tags): - # type: (List[Tag]) -> int - """Return the lowest index that one of the wheel's file_tag combinations - achieves in the given list of supported tags. - - For example, if there are 8 supported tags and one of the file tags - is first in the list, then return 0. - - :param tags: the PEP 425 tags to check the wheel against, in order - with most preferred first. - - :raises ValueError: If none of the wheel's file tags match one of - the supported tags. - """ - return min(tags.index(tag) for tag in self.file_tags if tag in tags) - - def supported(self, tags): - # type: (List[Tag]) -> bool - """Return whether the wheel is compatible with one of the given tags. - - :param tags: the PEP 425 tags to check the wheel against. - """ - return not self.file_tags.isdisjoint(tags) diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/network/__init__.py deleted file mode 100644 index b51bde91..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Contains purely network-related utilities. -""" diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index a31fb14943cd48b726527a7d4423ce683352f0da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmWIL<>g`kf{3<5@kT)UF^Gc<7=auIATH(r5-AK(3@MDk44O<;+RpiTC5f4N#R>(b zMX5QJ3VEp|<@rU~xO5>!;9FUxTd}dxrYEfQdjy}{5{dk~I bW=VX!UP0w84x8Nkl+v73JCI9112F>tM|(S- diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc deleted file mode 100644 index f7c5ea4659371e28c6f60c6c289d5b081a1d039d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6985 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc deleted file mode 100644 index 6548fa918fed88b8b65840fd5ab37d7c3ad36efa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2691 zcmaJ@TW=dh6rS0Oz1}#9lZNyLbg9I}Kpn(QAP}^T=tZb*Nm|Wad+1aUt`uXY0nHU-nxJPUXaAe8V}OE%6QHT6|1x?I{r&IKIyipo=VC>@t;&4 z7x5|=Fw?jmOTLJ^aBw5d4hP;6msMFv-nR5i%+})s97Zayq8?c3y5Lm?bFj_lh3pF+ zu@pVd-g$iQakO~ryT$LLr3c;a?e0yO_3l=9mN-i&9%lTYjwCO_E1Mt`85)vzZ2)C= zwcitE9vM_Oz)O9V115z(`Kl?%tstI$&0WkJrKmTs8469I0O1Cyx3>~kGu+k z6DSrET8xJFQ__R-VfLOEI?Q1%B(}?HtPbBA^H>AEb>_1P_ZxnMzrd0iMa+euKp5uW2elVL7N;tT zbmPzoMAwl#>xpw<@d8RYijpjrGKxmw#mI`YAU=dw)<6)eMW^Us{sg_91J@_uVu>D> z>8CJIWSeq@9i+vg33` zHy^{s5lq*o^K|gWDVQg%UqL$o+ZWNr5{Mz$hY%XHbeBB)f)az8?pn_-@7O~dgZvP3 z;xqCCSt5U)(3j2JBbXblLK_%yp)Iij0N)1xrjE2zR=m)T;4wP@Zg22y5rBoJz0-hg zK=2hTjVjXesYjc1Fmn%$2oDKhDN0^(bOx0_BcHKH~iY)ILIi)u1QGEg|7qcF-2g zxh|lIX%N_6-htOp=~2gR*1U#S_a;o^Y0rz#(G;Vo{qbLkEL{=U4)vRGy>=q#x2zPM z1X~2t={Da$;SiOEQP;lGyEb_KVsz}(Qa@c_%l{1GtKYWO&oh=xaVdwO4w0`v|3w~?=d XaB5JRRujsz2`v|;Lz}jTm#F_QFw=*^ diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc deleted file mode 100644 index daa96072a14c41287b076a32e26b57c19a82e84f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4379 zcmbVPO>^7E8D1y>*2kr zsT#xc;P?Lsh6{}Si#jJC2c38E7MCo>BGzV+74gJsTc+l1Zfd)2o7!nRsO_YZx^34Y zStqHcUfVP6N-~kw+BMU5lgYH+uA6o>nM$YI)28huGwE!5*0d**Q|VlLEQ|%1=p5=F++fl9Xz6nn zEr~1pcDsT8i_r!2FPQ#o5np4Ci~YuX`Qt3f!^q!^6H)k&W3}yfWxgdvQTTBd#hp;) zvS`-6CZJmlOM6m$+!KW=(4M<~x3#{~S`V(@yw|!Ntles_V02-;>FQ`B)Q{pwNX$8_ zd#krlPsK&BDf2Ywgq>}Hff;z0FbQo`sL5scvutKcW2+UDZRuIJai4c}p&$-LYw8^w4Yt zuR-PSXb>j**3ceUJC@=*_AZx8XgfnEb5U1@j&cVMBq{@2z7tso)j>sh1AE^(Zu< zePMbI&8nFJQ?vVgSRJ^O+Ta@9ZbL3Q7PH+Zdn_0yq$<wEO#D7K<<|J6znyev-AjU4x@IKFx3+}TPMmG#`V^G5vbiZbDt;vH zh({vPRT99_v~#QV{#{w6m8306A+h1fGqj77z|eJl?B2mfD0N-sDoldXCbdl`tC^2Q z=9E+ByyF$xEq&7%U|ApxGkq%PO3@7^U9$`)4Gb4=qF}Da>z2n|?s3PO<(@Uo>wMaB zEf23#*4*JW%sMbO&iJ>e|0}Oz?Q?EOS26}yM?=8{5BPu`lJczn2Q?qhTA0NO7VN8S z;a?&ZWML{U`H#rCe2O@J=wBas;(IYdP67Em^Gi2unoSUUcwT6y8>(&XZG?r{1j_ct z8$OG`Vlnz|F!J(XEO`$nEjS8Rkv~G&F>UJOAwxO36Wv&`1B-6-TR!A)CHnv=>(ClH z14q81Y~wy?cV8ROoq2!X9CtO8#s7QZtA3b8W)~?`Pi6+UNNk3^M46mG@cHqk8Aptu z;kfWc+EsfcSn`KBcf-+kXDfzr(OH5LOl`wZ&7~3SPLF|!jzQP6qc0tyr7M9#z|$`F z3Dd&t{T$ZiH@;)P-{B;Mp$P7@RkIx1v*cSCdk%AQDq}~Vp@HDUhOi^DCWAI`mp;(8 z2OI%|D+e`*#3Ca-6sxLo;Ets2$T{RA{j4IKI6tGEoZ<=gtU{)`Ys)9f+nG3UsCRg@ zi+pkkAhWP z#1#ixrqZ$M-#WH~m@;e4p$EPH0y0nOog(2;!lE=zdOtAK@Q_C~v`aR?2Rw43N^C_g zQiE-L&^|;uAJ`^Ed}F;Ve~!h{KsEErPDgar@=DgpBMQGB5YAMr_SPF*5@OmdloVmw za10>2VhD@DQP0XShO;2rBTa;=SHO#^Mae)6P`aiVes*AMIKQ%s8b1c!Kvjzc0tRT>}AV~A5ha4Q}dJufv3zKq2-k}d3BWYTc z$K*{Ef5vO#H4vlz_anB1+2;|993Te^0&=ddjn63LQ{>6U(j)9hStqe0)Z{G;5_=6s z_MoSbV@q02dAniD+mMheRJ=;X@qNry=#GEITNstO!0Yt!S&k5U&OwfN?k3ibdG5fX zFnFJ3ZxYW1v#ZIQ78}|Y>n|whpb|mdJ1zpAb%?Rg*nRc}Sntq&Vm|;2&iDfcp2xw} zIPIirRKwLK_w9W$FmU4wCa?+Oz93ir<89<^A6BhOw$-Q`sF2@_*Ydb0EAj#&3 e1Xrim{N^ilL!iwFui2jGUBx@&EqE7ar~U_J%~pf} diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc deleted file mode 100644 index de36e2c1cb16508da3ab72b3f7be9e82a27ffc93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9217 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 8365ec158c29b10ff59879f9f45414d79f0a3797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706 zcmYjO%Wl&^6rCA6iLuhO$^xXa@zzq~Ah7|d;uS&(6$Z5lG?tL%dZxsUUzr&zOqi3D2rS$7pwN`@!K&x_It<~p-Xg$SD0c-zLMwYgZ+uD$UB75to5_@!9dWuxqNVxT(R7V9L{DH6H++ah7X*Q7gq^oj+`)uMly2ZNtI89XFFgop!F7I zaY0!a7rA7)^j%XKJesSzkeo%CYCV;bC+C%9ea;K6OvqB#P!``TMcHe~P$WyHYU}Tx zh__(ee~-H|E4yVAA7%vTSgO`m|(sKFTQK3yP)fZuoPNwZ@U#QgE>>d z^@+H?joM$+w&lI+vT{)-`A2SQLVW{j`WG#}p6f=~)hz1}l&h3I!hnRn_#SBz6E}_j DgFm?L diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc deleted file mode 100644 index 799015421509009f244263879c95545a53045c1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1574 zcmZuxOOGQp5VpJB&m;qkK)fLmAP8tO2ZRI?ppjNA9MEXQ4%(qFo=)2{=}f=YcIFXv zIKYY%T=)gak-x#u@RbvPfdf$0$*e}OR$Qqnm+jAARrR-nK}=wr{Pa8j%qQdzH0}-t z#sN%y1VWI62r8U{CKUeN!YSRvrRZY?E4{?)bg%HsAPFgvbQQ^XO_Sc2MED|jOhh2P zS^q~j83^YA8HJ0tuFFC-S&>i1$11IKQ!6vf%chW}tW0Y1x{CjVtI6Sr+EB?ybE%C6 zeX!ZcVJifJ!)sEdWrneLhYQ95O#L*zO+X z%}Iyr38uw2N2>Gv~a_jY)o zpnVUfejkJ(GrDqG(zdv$cA8TG+$>^;MoRztAt!{z>Yl2v@FhSlvhGtbJ${o?HU}XB^RlYCNE{u z+eE;LM*l|CbAaNngMCvr`%T{L&8sHOE~MDIno3#heKMcid^ou&aBUyp8L6tY*sr9y zs@28*hS+g)qXIbQMVLASLFf*RX-F5Z{y#C}+gD~t;O)So#@UhiD=00Qk(RcOfFc&; z%wKv2$@PFxfAKLEbxxN7M7cB8`mNgrSRKExW!Q!*Z%rs^Sw}iq1#LJB*YqI}&xna; z@kOkDreqmWvUth#R(;{M(QGi=Y5g@c#}DKo`3UY@M&Cy#k&DpCYl9pdk6g=u;M4|FnF^`2^|etlEf;Tmb$om@luFfV_>LZ4P4hwy&!sVW zbq1x`@BIR=wSG~bpG#%KOywre(gOQ(yP>x^k!Q7#qgV~PTc>zyFik5_z_$Lj ziTR`!H|k}Kz}7X|x`0*}XyXXtHn_mZ`>u5rEp)?#Q4v@t8$9F>N zL%Hly240^ye>1jt2&BDjL41B&3YRe&-wQs1Lwn17r{qW_!>EV}2 None - self.prompting = prompting - self.index_urls = index_urls - self.passwords = {} # type: Dict[str, AuthInfo] - # When the user is prompted to enter credentials and keyring is - # available, we will offer to save them. If the user accepts, - # this value is set to the credentials they entered. After the - # request authenticates, the caller should call - # ``save_credentials`` to save these. - self._credentials_to_save = None # type: Optional[Credentials] - - def _get_index_url(self, url): - """Return the original index URL matching the requested URL. - - Cached or dynamically generated credentials may work against - the original index URL rather than just the netloc. - - The provided url should have had its username and password - removed already. If the original index url had credentials then - they will be included in the return value. - - Returns None if no matching index was found, or if --no-index - was specified by the user. - """ - if not url or not self.index_urls: - return None - - for u in self.index_urls: - prefix = remove_auth_from_url(u).rstrip("/") + "/" - if url.startswith(prefix): - return u - - def _get_new_credentials(self, original_url, allow_netrc=True, - allow_keyring=True): - """Find and return credentials for the specified URL.""" - # Split the credentials and netloc from the url. - url, netloc, url_user_password = split_auth_netloc_from_url( - original_url, - ) - - # Start with the credentials embedded in the url - username, password = url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in url for %s", netloc) - return url_user_password - - # Find a matching index url for this request - index_url = self._get_index_url(url) - if index_url: - # Split the credentials from the url. - index_info = split_auth_netloc_from_url(index_url) - if index_info: - index_url, _, index_url_user_password = index_info - logger.debug("Found index url %s", index_url) - - # If an index URL was found, try its embedded credentials - if index_url and index_url_user_password[0] is not None: - username, password = index_url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in index url for %s", netloc) - return index_url_user_password - - # Get creds from netrc if we still don't have them - if allow_netrc: - netrc_auth = get_netrc_auth(original_url) - if netrc_auth: - logger.debug("Found credentials in netrc for %s", netloc) - return netrc_auth - - # If we don't have a password and keyring is available, use it. - if allow_keyring: - # The index url is more specific than the netloc, so try it first - kr_auth = ( - get_keyring_auth(index_url, username) or - get_keyring_auth(netloc, username) - ) - if kr_auth: - logger.debug("Found credentials in keyring for %s", netloc) - return kr_auth - - return username, password - - def _get_url_and_credentials(self, original_url): - """Return the credentials to use for the provided URL. - - If allowed, netrc and keyring may be used to obtain the - correct credentials. - - Returns (url_without_credentials, username, password). Note - that even if the original URL contains credentials, this - function may return a different username and password. - """ - url, netloc, _ = split_auth_netloc_from_url(original_url) - - # Use any stored credentials that we have for this netloc - username, password = self.passwords.get(netloc, (None, None)) - - if username is None and password is None: - # No stored credentials. Acquire new credentials without prompting - # the user. (e.g. from netrc, keyring, or the URL itself) - username, password = self._get_new_credentials(original_url) - - if username is not None or password is not None: - # Convert the username and password if they're None, so that - # this netloc will show up as "cached" in the conditional above. - # Further, HTTPBasicAuth doesn't accept None, so it makes sense to - # cache the value that is going to be used. - username = username or "" - password = password or "" - - # Store any acquired credentials. - self.passwords[netloc] = (username, password) - - assert ( - # Credentials were found - (username is not None and password is not None) or - # Credentials were not found - (username is None and password is None) - ), "Could not load credentials from url: {}".format(original_url) - - return url, username, password - - def __call__(self, req): - # Get credentials for this request - url, username, password = self._get_url_and_credentials(req.url) - - # Set the url of the request to the url without any credentials - req.url = url - - if username is not None and password is not None: - # Send the basic auth with this request - req = HTTPBasicAuth(username, password)(req) - - # Attach a hook to handle 401 responses - req.register_hook("response", self.handle_401) - - return req - - # Factored out to allow for easy patching in tests - def _prompt_for_password(self, netloc): - username = ask_input("User for {}: ".format(netloc)) - if not username: - return None, None - auth = get_keyring_auth(netloc, username) - if auth: - return auth[0], auth[1], False - password = ask_password("Password: ") - return username, password, True - - # Factored out to allow for easy patching in tests - def _should_save_password_to_keyring(self): - if not keyring: - return False - return ask("Save credentials to keyring [y/N]: ", ["y", "n"]) == "y" - - def handle_401(self, resp, **kwargs): - # We only care about 401 responses, anything else we want to just - # pass through the actual response - if resp.status_code != 401: - return resp - - # We are not able to prompt the user so simply return the response - if not self.prompting: - return resp - - parsed = urllib_parse.urlparse(resp.url) - - # Prompt the user for a new username and password - username, password, save = self._prompt_for_password(parsed.netloc) - - # Store the new username and password to use for future requests - self._credentials_to_save = None - if username is not None and password is not None: - self.passwords[parsed.netloc] = (username, password) - - # Prompt to save the password to keyring - if save and self._should_save_password_to_keyring(): - self._credentials_to_save = (parsed.netloc, username, password) - - # Consume content and release the original connection to allow our new - # request to reuse the same one. - resp.content - resp.raw.release_conn() - - # Add our new username and password to the request - req = HTTPBasicAuth(username or "", password or "")(resp.request) - req.register_hook("response", self.warn_on_401) - - # On successful request, save the credentials that were used to - # keyring. (Note that if the user responded "no" above, this member - # is not set and nothing will be saved.) - if self._credentials_to_save: - req.register_hook("response", self.save_credentials) - - # Send our new request - new_resp = resp.connection.send(req, **kwargs) - new_resp.history.append(resp) - - return new_resp - - def warn_on_401(self, resp, **kwargs): - """Response callback to warn about incorrect credentials.""" - if resp.status_code == 401: - logger.warning( - '401 Error, Credentials not correct for %s', resp.request.url, - ) - - def save_credentials(self, resp, **kwargs): - """Response callback to save credentials on success.""" - assert keyring is not None, "should never reach here without keyring" - if not keyring: - return - - creds = self._credentials_to_save - self._credentials_to_save = None - if creds and resp.status_code < 400: - try: - logger.info('Saving credentials to keyring') - keyring.set_password(*creds) - except Exception: - logger.exception('Failed to save credentials') diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/cache.py b/env/lib/python3.8/site-packages/pip/_internal/network/cache.py deleted file mode 100644 index c9386e17..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/cache.py +++ /dev/null @@ -1,81 +0,0 @@ -"""HTTP cache implementation. -""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -import os -from contextlib import contextmanager - -from pip._vendor.cachecontrol.cache import BaseCache -from pip._vendor.cachecontrol.caches import FileCache -from pip._vendor.requests.models import Response - -from pip._internal.utils.filesystem import adjacent_tmp_file, replace -from pip._internal.utils.misc import ensure_dir -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional - - -def is_from_cache(response): - # type: (Response) -> bool - return getattr(response, "from_cache", False) - - -@contextmanager -def suppressed_cache_errors(): - """If we can't access the cache then we can just skip caching and process - requests as if caching wasn't enabled. - """ - try: - yield - except (OSError, IOError): - pass - - -class SafeFileCache(BaseCache): - """ - A file based cache which is safe to use even when the target directory may - not be accessible or writable. - """ - - def __init__(self, directory): - # type: (str) -> None - assert directory is not None, "Cache directory must not be None." - super(SafeFileCache, self).__init__() - self.directory = directory - - def _get_cache_path(self, name): - # type: (str) -> str - # From cachecontrol.caches.file_cache.FileCache._fn, brought into our - # class for backwards-compatibility and to avoid using a non-public - # method. - hashed = FileCache.encode(name) - parts = list(hashed[:5]) + [hashed] - return os.path.join(self.directory, *parts) - - def get(self, key): - # type: (str) -> Optional[bytes] - path = self._get_cache_path(key) - with suppressed_cache_errors(): - with open(path, 'rb') as f: - return f.read() - - def set(self, key, value): - # type: (str, bytes) -> None - path = self._get_cache_path(key) - with suppressed_cache_errors(): - ensure_dir(os.path.dirname(path)) - - with adjacent_tmp_file(path) as f: - f.write(value) - - replace(f.name, path) - - def delete(self, key): - # type: (str) -> None - path = self._get_cache_path(key) - with suppressed_cache_errors(): - os.remove(path) diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/download.py b/env/lib/python3.8/site-packages/pip/_internal/network/download.py deleted file mode 100644 index 2f3e08ae..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/download.py +++ /dev/null @@ -1,200 +0,0 @@ -"""Download files with progress indicators. -""" -import cgi -import logging -import mimetypes -import os - -from pip._vendor import requests -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE - -from pip._internal.cli.progress_bars import DownloadProgressProvider -from pip._internal.models.index import PyPI -from pip._internal.network.cache import is_from_cache -from pip._internal.network.utils import response_chunks -from pip._internal.utils.misc import ( - format_size, - redact_auth_from_url, - splitext, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterable, Optional - - from pip._vendor.requests.models import Response - - from pip._internal.models.link import Link - from pip._internal.network.session import PipSession - -logger = logging.getLogger(__name__) - - -def _get_http_response_size(resp): - # type: (Response) -> Optional[int] - try: - return int(resp.headers['content-length']) - except (ValueError, KeyError, TypeError): - return None - - -def _prepare_download( - resp, # type: Response - link, # type: Link - progress_bar # type: str -): - # type: (...) -> Iterable[bytes] - total_length = _get_http_response_size(resp) - - if link.netloc == PyPI.file_storage_domain: - url = link.show_url - else: - url = link.url_without_fragment - - logged_url = redact_auth_from_url(url) - - if total_length: - logged_url = '{} ({})'.format(logged_url, format_size(total_length)) - - if is_from_cache(resp): - logger.info("Using cached %s", logged_url) - else: - logger.info("Downloading %s", logged_url) - - if logger.getEffectiveLevel() > logging.INFO: - show_progress = False - elif is_from_cache(resp): - show_progress = False - elif not total_length: - show_progress = True - elif total_length > (40 * 1000): - show_progress = True - else: - show_progress = False - - chunks = response_chunks(resp, CONTENT_CHUNK_SIZE) - - if not show_progress: - return chunks - - return DownloadProgressProvider( - progress_bar, max=total_length - )(chunks) - - -def sanitize_content_filename(filename): - # type: (str) -> str - """ - Sanitize the "filename" value from a Content-Disposition header. - """ - return os.path.basename(filename) - - -def parse_content_disposition(content_disposition, default_filename): - # type: (str, str) -> str - """ - Parse the "filename" value from a Content-Disposition header, and - return the default filename if the result is empty. - """ - _type, params = cgi.parse_header(content_disposition) - filename = params.get('filename') - if filename: - # We need to sanitize the filename to prevent directory traversal - # in case the filename contains ".." path parts. - filename = sanitize_content_filename(filename) - return filename or default_filename - - -def _get_http_response_filename(resp, link): - # type: (Response, Link) -> str - """Get an ideal filename from the given HTTP response, falling back to - the link filename if not provided. - """ - filename = link.filename # fallback - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get('content-disposition') - if content_disposition: - filename = parse_content_disposition(content_disposition, filename) - ext = splitext(filename)[1] # type: Optional[str] - if not ext: - ext = mimetypes.guess_extension( - resp.headers.get('content-type', '') - ) - if ext: - filename += ext - if not ext and link.url != resp.url: - ext = os.path.splitext(resp.url)[1] - if ext: - filename += ext - return filename - - -def _http_get_download(session, link): - # type: (PipSession, Link) -> Response - target_url = link.url.split('#', 1)[0] - resp = session.get( - target_url, - # We use Accept-Encoding: identity here because requests - # defaults to accepting compressed responses. This breaks in - # a variety of ways depending on how the server is configured. - # - Some servers will notice that the file isn't a compressible - # file and will leave the file alone and with an empty - # Content-Encoding - # - Some servers will notice that the file is already - # compressed and will leave the file alone and will add a - # Content-Encoding: gzip header - # - Some servers won't notice anything at all and will take - # a file that's already been compressed and compress it again - # and set the Content-Encoding: gzip header - # By setting this to request only the identity encoding We're - # hoping to eliminate the third case. Hopefully there does not - # exist a server which when given a file will notice it is - # already compressed and that you're not asking for a - # compressed file and will then decompress it before sending - # because if that's the case I don't think it'll ever be - # possible to make this work. - headers={"Accept-Encoding": "identity"}, - stream=True, - ) - resp.raise_for_status() - return resp - - -class Download(object): - def __init__( - self, - response, # type: Response - filename, # type: str - chunks, # type: Iterable[bytes] - ): - # type: (...) -> None - self.response = response - self.filename = filename - self.chunks = chunks - - -class Downloader(object): - def __init__( - self, - session, # type: PipSession - progress_bar, # type: str - ): - # type: (...) -> None - self._session = session - self._progress_bar = progress_bar - - def __call__(self, link): - # type: (Link) -> Download - try: - resp = _http_get_download(self._session, link) - except requests.HTTPError as e: - logger.critical( - "HTTP error %s while getting %s", e.response.status_code, link - ) - raise - - return Download( - resp, - _get_http_response_filename(resp, link), - _prepare_download(resp, link, self._progress_bar), - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/session.py b/env/lib/python3.8/site-packages/pip/_internal/network/session.py deleted file mode 100644 index 39a4a546..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/session.py +++ /dev/null @@ -1,421 +0,0 @@ -"""PipSession and supporting code, containing all pip-specific -network request configuration and behavior. -""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -import email.utils -import json -import logging -import mimetypes -import os -import platform -import sys -import warnings - -from pip._vendor import requests, six, urllib3 -from pip._vendor.cachecontrol import CacheControlAdapter -from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter -from pip._vendor.requests.models import Response -from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.urllib3.exceptions import InsecureRequestWarning - -from pip import __version__ -from pip._internal.network.auth import MultiDomainBasicAuth -from pip._internal.network.cache import SafeFileCache -# Import ssl from compat so the initial import occurs in only one place. -from pip._internal.utils.compat import has_tls, ipaddress -from pip._internal.utils.glibc import libc_ver -from pip._internal.utils.misc import ( - build_url_from_netloc, - get_installed_version, - parse_netloc, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import url_to_path - -if MYPY_CHECK_RUNNING: - from typing import ( - Iterator, List, Optional, Tuple, Union, - ) - - from pip._internal.models.link import Link - - SecureOrigin = Tuple[str, str, Optional[Union[int, str]]] - - -logger = logging.getLogger(__name__) - - -# Ignore warning raised when using --trusted-host. -warnings.filterwarnings("ignore", category=InsecureRequestWarning) - - -SECURE_ORIGINS = [ - # protocol, hostname, port - # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) - ("https", "*", "*"), - ("*", "localhost", "*"), - ("*", "127.0.0.0/8", "*"), - ("*", "::1/128", "*"), - ("file", "*", None), - # ssh is always secure. - ("ssh", "*", "*"), -] # type: List[SecureOrigin] - - -# These are environment variables present when running under various -# CI systems. For each variable, some CI systems that use the variable -# are indicated. The collection was chosen so that for each of a number -# of popular systems, at least one of the environment variables is used. -# This list is used to provide some indication of and lower bound for -# CI traffic to PyPI. Thus, it is okay if the list is not comprehensive. -# For more background, see: https://github.com/pypa/pip/issues/5499 -CI_ENVIRONMENT_VARIABLES = ( - # Azure Pipelines - 'BUILD_BUILDID', - # Jenkins - 'BUILD_ID', - # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI - 'CI', - # Explicit environment variable. - 'PIP_IS_CI', -) - - -def looks_like_ci(): - # type: () -> bool - """ - Return whether it looks like pip is running under CI. - """ - # We don't use the method of checking for a tty (e.g. using isatty()) - # because some CI systems mimic a tty (e.g. Travis CI). Thus that - # method doesn't provide definitive information in either direction. - return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES) - - -def user_agent(): - """ - Return a string representing the user agent. - """ - data = { - "installer": {"name": "pip", "version": __version__}, - "python": platform.python_version(), - "implementation": { - "name": platform.python_implementation(), - }, - } - - if data["implementation"]["name"] == 'CPython': - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'PyPy': - if sys.pypy_version_info.releaselevel == 'final': - pypy_version_info = sys.pypy_version_info[:3] - else: - pypy_version_info = sys.pypy_version_info - data["implementation"]["version"] = ".".join( - [str(x) for x in pypy_version_info] - ) - elif data["implementation"]["name"] == 'Jython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'IronPython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - - if sys.platform.startswith("linux"): - from pip._vendor import distro - distro_infos = dict(filter( - lambda x: x[1], - zip(["name", "version", "id"], distro.linux_distribution()), - )) - libc = dict(filter( - lambda x: x[1], - zip(["lib", "version"], libc_ver()), - )) - if libc: - distro_infos["libc"] = libc - if distro_infos: - data["distro"] = distro_infos - - if sys.platform.startswith("darwin") and platform.mac_ver()[0]: - data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} - - if platform.system(): - data.setdefault("system", {})["name"] = platform.system() - - if platform.release(): - data.setdefault("system", {})["release"] = platform.release() - - if platform.machine(): - data["cpu"] = platform.machine() - - if has_tls(): - import _ssl as ssl - data["openssl_version"] = ssl.OPENSSL_VERSION - - setuptools_version = get_installed_version("setuptools") - if setuptools_version is not None: - data["setuptools_version"] = setuptools_version - - # Use None rather than False so as not to give the impression that - # pip knows it is not being run under CI. Rather, it is a null or - # inconclusive result. Also, we include some value rather than no - # value to make it easier to know that the check has been run. - data["ci"] = True if looks_like_ci() else None - - user_data = os.environ.get("PIP_USER_AGENT_USER_DATA") - if user_data is not None: - data["user_data"] = user_data - - return "{data[installer][name]}/{data[installer][version]} {json}".format( - data=data, - json=json.dumps(data, separators=(",", ":"), sort_keys=True), - ) - - -class LocalFSAdapter(BaseAdapter): - - def send(self, request, stream=None, timeout=None, verify=None, cert=None, - proxies=None): - pathname = url_to_path(request.url) - - resp = Response() - resp.status_code = 200 - resp.url = request.url - - try: - stats = os.stat(pathname) - except OSError as exc: - resp.status_code = 404 - resp.raw = exc - else: - modified = email.utils.formatdate(stats.st_mtime, usegmt=True) - content_type = mimetypes.guess_type(pathname)[0] or "text/plain" - resp.headers = CaseInsensitiveDict({ - "Content-Type": content_type, - "Content-Length": stats.st_size, - "Last-Modified": modified, - }) - - resp.raw = open(pathname, "rb") - resp.close = resp.raw.close - - return resp - - def close(self): - pass - - -class InsecureHTTPAdapter(HTTPAdapter): - - def cert_verify(self, conn, url, verify, cert): - super(InsecureHTTPAdapter, self).cert_verify( - conn=conn, url=url, verify=False, cert=cert - ) - - -class InsecureCacheControlAdapter(CacheControlAdapter): - - def cert_verify(self, conn, url, verify, cert): - super(InsecureCacheControlAdapter, self).cert_verify( - conn=conn, url=url, verify=False, cert=cert - ) - - -class PipSession(requests.Session): - - timeout = None # type: Optional[int] - - def __init__(self, *args, **kwargs): - """ - :param trusted_hosts: Domains not to emit warnings for when not using - HTTPS. - """ - retries = kwargs.pop("retries", 0) - cache = kwargs.pop("cache", None) - trusted_hosts = kwargs.pop("trusted_hosts", []) # type: List[str] - index_urls = kwargs.pop("index_urls", None) - - super(PipSession, self).__init__(*args, **kwargs) - - # Namespace the attribute with "pip_" just in case to prevent - # possible conflicts with the base class. - self.pip_trusted_origins = [] # type: List[Tuple[str, Optional[int]]] - - # Attach our User Agent to the request - self.headers["User-Agent"] = user_agent() - - # Attach our Authentication handler to the session - self.auth = MultiDomainBasicAuth(index_urls=index_urls) - - # Create our urllib3.Retry instance which will allow us to customize - # how we handle retries. - retries = urllib3.Retry( - # Set the total number of retries that a particular request can - # have. - total=retries, - - # A 503 error from PyPI typically means that the Fastly -> Origin - # connection got interrupted in some way. A 503 error in general - # is typically considered a transient error so we'll go ahead and - # retry it. - # A 500 may indicate transient error in Amazon S3 - # A 520 or 527 - may indicate transient error in CloudFlare - status_forcelist=[500, 503, 520, 527], - - # Add a small amount of back off between failed requests in - # order to prevent hammering the service. - backoff_factor=0.25, - ) - - # Our Insecure HTTPAdapter disables HTTPS validation. It does not - # support caching so we'll use it for all http:// URLs. - # If caching is disabled, we will also use it for - # https:// hosts that we've marked as ignoring - # TLS errors for (trusted-hosts). - insecure_adapter = InsecureHTTPAdapter(max_retries=retries) - - # We want to _only_ cache responses on securely fetched origins or when - # the host is specified as trusted. We do this because - # we can't validate the response of an insecurely/untrusted fetched - # origin, and we don't want someone to be able to poison the cache and - # require manual eviction from the cache to fix it. - if cache: - secure_adapter = CacheControlAdapter( - cache=SafeFileCache(cache), - max_retries=retries, - ) - self._trusted_host_adapter = InsecureCacheControlAdapter( - cache=SafeFileCache(cache), - max_retries=retries, - ) - else: - secure_adapter = HTTPAdapter(max_retries=retries) - self._trusted_host_adapter = insecure_adapter - - self.mount("https://", secure_adapter) - self.mount("http://", insecure_adapter) - - # Enable file:// urls - self.mount("file://", LocalFSAdapter()) - - for host in trusted_hosts: - self.add_trusted_host(host, suppress_logging=True) - - def add_trusted_host(self, host, source=None, suppress_logging=False): - # type: (str, Optional[str], bool) -> None - """ - :param host: It is okay to provide a host that has previously been - added. - :param source: An optional source string, for logging where the host - string came from. - """ - if not suppress_logging: - msg = 'adding trusted host: {!r}'.format(host) - if source is not None: - msg += ' (from {})'.format(source) - logger.info(msg) - - host_port = parse_netloc(host) - if host_port not in self.pip_trusted_origins: - self.pip_trusted_origins.append(host_port) - - self.mount( - build_url_from_netloc(host) + '/', - self._trusted_host_adapter - ) - if not host_port[1]: - # Mount wildcard ports for the same host. - self.mount( - build_url_from_netloc(host) + ':', - self._trusted_host_adapter - ) - - def iter_secure_origins(self): - # type: () -> Iterator[SecureOrigin] - for secure_origin in SECURE_ORIGINS: - yield secure_origin - for host, port in self.pip_trusted_origins: - yield ('*', host, '*' if port is None else port) - - def is_secure_origin(self, location): - # type: (Link) -> bool - # Determine if this url used a secure transport mechanism - parsed = urllib_parse.urlparse(str(location)) - origin_protocol, origin_host, origin_port = ( - parsed.scheme, parsed.hostname, parsed.port, - ) - - # The protocol to use to see if the protocol matches. - # Don't count the repository type as part of the protocol: in - # cases such as "git+ssh", only use "ssh". (I.e., Only verify against - # the last scheme.) - origin_protocol = origin_protocol.rsplit('+', 1)[-1] - - # Determine if our origin is a secure origin by looking through our - # hardcoded list of secure origins, as well as any additional ones - # configured on this PackageFinder instance. - for secure_origin in self.iter_secure_origins(): - secure_protocol, secure_host, secure_port = secure_origin - if origin_protocol != secure_protocol and secure_protocol != "*": - continue - - try: - addr = ipaddress.ip_address( - None - if origin_host is None - else six.ensure_text(origin_host) - ) - network = ipaddress.ip_network( - six.ensure_text(secure_host) - ) - except ValueError: - # We don't have both a valid address or a valid network, so - # we'll check this origin against hostnames. - if ( - origin_host and - origin_host.lower() != secure_host.lower() and - secure_host != "*" - ): - continue - else: - # We have a valid address and network, so see if the address - # is contained within the network. - if addr not in network: - continue - - # Check to see if the port matches. - if ( - origin_port != secure_port and - secure_port != "*" and - secure_port is not None - ): - continue - - # If we've gotten here, then this origin matches the current - # secure origin and we should return True - return True - - # If we've gotten to this point, then the origin isn't secure and we - # will not accept it as a valid location to search. We will however - # log a warning that we are ignoring it. - logger.warning( - "The repository located at %s is not a trusted or secure host and " - "is being ignored. If this repository is available via HTTPS we " - "recommend you use HTTPS instead, otherwise you may silence " - "this warning and allow it anyway with '--trusted-host %s'.", - origin_host, - origin_host, - ) - - return False - - def request(self, method, url, *args, **kwargs): - # Allow setting a default timeout on a session - kwargs.setdefault("timeout", self.timeout) - - # Dispatch the actual request - return super(PipSession, self).request(method, url, *args, **kwargs) diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/utils.py b/env/lib/python3.8/site-packages/pip/_internal/network/utils.py deleted file mode 100644 index a19050b0..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/utils.py +++ /dev/null @@ -1,48 +0,0 @@ -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterator - - -def response_chunks(response, chunk_size=CONTENT_CHUNK_SIZE): - # type: (Response, int) -> Iterator[bytes] - """Given a requests Response, provide the data chunks. - """ - try: - # Special case for urllib3. - for chunk in response.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False, - ): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = response.raw.read(chunk_size) - if not chunk: - break - yield chunk diff --git a/env/lib/python3.8/site-packages/pip/_internal/network/xmlrpc.py b/env/lib/python3.8/site-packages/pip/_internal/network/xmlrpc.py deleted file mode 100644 index 121edd93..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/network/xmlrpc.py +++ /dev/null @@ -1,44 +0,0 @@ -"""xmlrpclib.Transport implementation -""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -import logging - -from pip._vendor import requests -# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import -from pip._vendor.six.moves import xmlrpc_client # type: ignore -from pip._vendor.six.moves.urllib import parse as urllib_parse - -logger = logging.getLogger(__name__) - - -class PipXmlrpcTransport(xmlrpc_client.Transport): - """Provide a `xmlrpclib.Transport` implementation via a `PipSession` - object. - """ - - def __init__(self, index_url, session, use_datetime=False): - xmlrpc_client.Transport.__init__(self, use_datetime) - index_parts = urllib_parse.urlparse(index_url) - self._scheme = index_parts.scheme - self._session = session - - def request(self, host, handler, request_body, verbose=False): - parts = (self._scheme, host, handler, None, None, None) - url = urllib_parse.urlunparse(parts) - try: - headers = {'Content-Type': 'text/xml'} - response = self._session.post(url, data=request_body, - headers=headers, stream=True) - response.raise_for_status() - self.verbose = verbose - return self.parse_response(response.raw) - except requests.HTTPError as exc: - logger.critical( - "HTTP error %s while getting %s", - exc.response.status_code, url, - ) - raise diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/operations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 58ee8a097cd39f7be5d0b88306041d3e42cee6a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmWIL<>g`kf{3<5@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vNza+OnzaXm@auWQ_&Y5o9~+C?7|J&dgByXtP0kWCF!5_8EVTm5q&+*a(^^o|^IGDh z^`NfjPU5DGprPmW#7mn&Q_tO`l}-gyrXkFuX>sPY8O(?&`44DnB(v#UFsG%wkJp#RYah~=g|B&6gvFb@#izE}Aq(E))BMa!Bls3y;xl~qr5UX9Ier#9SNS|& z!0)&DB0q=U_c?oPw3iRw|3#FM|SISI+(N3eD2zjh>8E*~g zonbeVVcb`Flq8`%IR@eL+af<^34ZF70(n?I%9`<1SV z8?@`C^^^X7>2Ba1(N-c#`%c`+OZVpkxaeTa|Awa{e_LN9sz5HeJE}_rPITFTb0c*4nqY`xzGeRrmD0F zN~KM(D@`HKk}4wq`glE02kV1)aDCXPqk><5u_Hus{RhLX{qJt=C&XI^x^f|bfc0!3 zq>cf#-q{hI-r8WlywZ^(%0)Qw>aZ)b^aPXF@G7+gV$@vIW439V)23%KbIF`x)1cA^ zufs@U{18g&7#kSsZy*Iw(R1Yt;p8PS0-P`mt1y6&zmDwOIE3FdbqEuOru=B{LSYp4 zvaw4jN=EgZ74=;UC~^z8FnV?QYi^Gk*t4O#A^S8VRAH|nZx^*A2Xgf;du^J=-fie| zp{qXfAm{Ej3Xj{o_KK<7g`*|0-?hfFHThNU6}7y{omZ@2gwev07qI7y_bl4O4OwB0 z@%QHqGN~VT0kN?$efZIjmEXzw3NA#R@HFD?cYU>!4HF*5+x<)mk{Luw3I2f}=VP9~ zC7=nI)Y0tcJ5lcENG!m&R&x9ff`uRTIRKguWuM@`m1T*D`W3u4J17xvADYv6jG+jR z+(h)S&3hVAZ%la+dnXW+m$59TPTlq{9o61853Xq(O@e3brVb=^YwgsbC&*gOffQ2U zW=c?MvwC8`-6|~@sR|E^UcE>!bka!n5F@U59wkG-v$P`4btIJyH4vS+8xtFbMds?O z(ovbr1&6X+wwrQ=G`&Zf>S?Sfe9I&RP_Xvj?JBM=IgFW89EtqFLWhYYC}fTY>)u|}#je`|CRdYrvPVC9iM5N8VYS&=c#fzRB<{?DCdn2>y#K~-EuY@C&QCFkQdr^>E+q6v<6pc zhUJ_#P`LG04}d|RC&@Qe;GFwEmrNj`s3aJU$2`lk7}6;-y#Lt$mOsYssbortw1%;P zp&o$fG|6=8yjc}jDy@Zm#E|@I@Oo_*33TM-HOw3&!uq(>I!I&e$SoY5=DdOmr+M)4 zMwSkSIT8!OVB7*sc12^aPk8*q8dZ)#3A~DnNxEivi8`7=ZySw{%7(Hd)TypU*Gaib z;_sA4Dm3l7yh$vI;Ic7(B?8-}DYZ`JRI~+bL@2Sk!@5Ay-;lKA4KRL%q3A7!;~?7b z$2@bMwV39fvNB!$9V-_GtcVr`<>v-Ul~u5wBUkoXC{XBMby@OJx=8AW?nw>^M28FzR;EN&r^t#QY8s4KPh8 zFys$G{)AD13F(DCl9CHmXqRbz+uUqlE9+s%vrZV6b?QIH88Jzq9}S<96r1IFvt-1vS*U-WyO1mvsJ|!{f7&5P8phkOrKD3jV^s|-B>jsesa26JB2z@B ziJT$w0Z8CItU6>gi$VRZvk diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc deleted file mode 100644 index b44058ba76db46995e2cda2fc363f6010cbf63fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5895 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 7fd5ae4f7988786c248bd2be086af1049ffa66b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmWIL<>g`kf{3<5@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vTza+OnzaXV!Z diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc deleted file mode 100644 index 8b509a12362c12f045414547341b99f59cf2584b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1208 zcmZux!EW3(5G5(CR^F~_J7^oD4hmiOU@d|+2m%B_QO8J%G{)9-P)8R+D>A#XDN-OQ z8*8jjDS9jN3-&R;(a+$ur~X1O=}_xkCqM{@yJXH{IzV^p6)l z9svkH!e>rkVkkolGa_(?+m&Pl)<6VRn1$G5q3Bdm7Pb41=vHwSW5i>91Xv{2s$SM> zv99={>Sukx@YOp1@)~CwEM{weplp+o-_W3U@xx1QbC%mYnQ+N~=SnwCQBy)0tFM~OHmttfI3*X|)aE`Bnd3cTAZDIuba2{Oa%g*oU z0s0jkqGNQsvz-%s70rWr=h`#Wxe(75#PFnAQq`DJPCzWCxhzd(62?sd{BV|(G8yfU z5(qu*^%59|+%{U8#7_B=Vo+OM#g^=(t@g!6r5M+8cd2kRATB&DC3Bk-p~gVPj8?e> ze%ZzLNb@?^K9=(-=VEp1psRgHxv5D?e>DbqT zw)Z)rj0;axDF=~TTL4_1x$ZbGPC10Mv9h#P4Vk$9>cC6UjibJApHjY26i(kG{S^fC z--{vG4C}JqZDj55W4o=>-AB!M_WgJ!JT|1Iv_MBLhN`~lPBUyH87^I=^~`PEH1BOL zcfg0)h6zOk6GT2lVML-Z#(f-O@?ksF-vBn)a$QQ9Dkybb==uq8srvx9@4$Py@}5HH z3zOb*xFGf3=aek;yiasdf^R>oGJ~fw(V=&A_fv%x%NqU@$nCV~8IY}XTDMOkJ=b{+ zWEkyVfm@q!`wK+QwTmg0dBq`@$mha!n`2A&N7L8dDt-)o)(HLtgJgU`!XU;m=>tD~ J61HJUl*-A9cYTbQFL&UKm(FH$-8q=!lX$}G)3V_E(nkt`~N z9KgcT}yn@6Ffqv_yIb?hj@h5-NK^wiEY-7@Xxq#M$l7d-;wuWr*>fn?bS})5gK9YzJpE; zaP{H6FA`3JkOyt>Yt{G_fGc!jdyw#8XFA(yHv?!_n)%e2c>_d@M(DdGW7-Mu;uK3T z=r`+o2cE;j#`GER-(#GrgQVDPS=wrUsB!;yBxm4?zdLJ1mapYWzFP7;jP@B_J=kR| zUHzo&4es>@so7hDFceJkFkKV*dCb*X&tSTiozsDgBj3&ky1AZ0+#`|Y8_UL47lex~ z)I`JEqz@=eBimk21q4-Xz+iG@czau1z-S5y(5nOh0j3`h-f?^ji6`cLw z8EMY6>e>=Y*Uf8ivoxXCE)X{h3vH*2YbOtjUG40NgacTO>GQhLPhdaHn5vK)3*Vfd zyX@38SW`DaAjietnd>;%g5Gg_=wW!92aVdu9a+?+^<&Wg7JZDqK^^o074E2Zgn<;^ zkUt#fEDI)K3rdynIHB9Md30^C{qzI!-X;y zGpTEo^~zY9;7AipX)3UEj4)9H%|^w2!uTsaTU}4`0jY@799O=|ATLn@N*trQP9aN@ zR7sPz+A;O)Z4xb>ms3V2Xnp{?$_V5e23g4Z*Qr(gndd-nzJFX7GV6T2P?vW>yLDaH z385k)1c(kUK>*}DZ0Hq$wmr?|Hv1uBc~zRndGOxlZK&F*YG0_wmD3d%`qq`I)5=_d zrEgxPR6xNt=v46P8&|3fa$~Y78+!S&!W4ID(nU97R(w4Unn#F9PD11@*r@_lp>Y9c kQ}AS!vEF(nXqmDNQxnt*2*>uYXZiU2vmESOP1{@k4>%q$p8x;= diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index b1316db80eb30dde370e76e6116dd986bd18bea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1306 zcmZuxO>Y}T7@isLmp4ubRfW_B!3a^Qmhf6tRUr^UP?M61;)YaJlRdCndne8&`^C&G z!De#-gt$~(Iod~l1Q&kBTsiR(?>84fBZfA%|_@C zZCo84Fg}7QzJw(~3C>X1e&Y~>O)`>q!VcDZoy^MZ(8h?_d=G3Zb8U)1e4>ay$wZrS8U_3fca=7rT z3v&ch`~piu5`5MbJ&C@nKcdS^cW2_yY6T^y(Z^^Q!B zLnOPW{&EBIofQFL+{N?zb($r#EEs)Q2nl2k*jIJRS>ADFgZ#s`2wwuy-h5=Z&Fz zU@DCl4@PlOlycptt#n*+dP}Uq{0jtJ1sx0wo5m*u~`ptskR`}!W_OvXtpb9S4svZXz*S=nctnvGwmBjX(1Vht3NC&#*L<8Xj%7e3?quSPj*!vcfr*Q$0*%GV%X$%7VgaL(fjC<^ZAi0+KZ uN9`$kkxALM0HXY4}^meBY;?2#T&w(vHre&-*lntf9M diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc deleted file mode 100644 index 34cd6f1e3ceeb5c48dbe2403877b59052e6865a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2576 zcma);TW{P%6o6-ZTd%W8+B9vs%T$zh5!nb31u9e_+O!lx3N5AWA~0UhWaGw{)y%kQ zw%(^Ao~ZZ>iFo3T-@wn9SDyF_+|Lw10%PnEw^&FS9la;CYnIu?{?s zF?x-3=YNK^kc}?YopQvBNRHB?-~#$#9&htVa#f8~S!OaCuvDsOXN&VJip5ZNZ9TVs zHnZL!6T3L8tUY_5DCf4j?T9x)ZX5ZDn(leb*{AaTnlcAu6u!A&gR0iP(XDOR z8gG2+qH!RcIuNEs;}NVdgtss&hr_fO_QuD~H!g;-FICP9CC`TUCc$|5KwegARH?J! zMp^LjsmG9{8`lW;xo!g>az{54l>~ z+~kQ$@9=eghiAGqU88m{ti5~vlJ7(VeMtCOUfIpw}$;;aA3Gq8$Y> z`JRYlp!&;|Rh5rcN9ky#Dn@a#&Dn}!W96-Cu>0CzH^XnMQCcW2AfT&&mxwXAa&=Ip z8Cz{g%J?u&c6*~;eYEjrhKt~`%G6PqOD;o0Jf8-ZLj$@1&w%>$kR_e~d4fkp`V}S0Qmk5vna7j$*ZiLB)6DG=O9}isz$J#9}uzI})-~KD*B6atk7n3j%JXV~AMHz0U8JE3a<7W!)j{E;pF)sy>wiOp4AZcv$f{S3O zh;uH()5%s@N?;ql2&uXTXMq!R+uD<*fVo8nx+VewsvXg-omdp0qHVCEtx{?SJ=f0d zGA+8Ec8zK6qt_9*svQ)FCA4w`4cNIH8n&9|ILe*|q@#wB$ZXQI0HNiVV1Rr98WQ-_ zv8+EW%lgBy0T1YPuy0$$`rUC57=Z&5#N*(?LZ1k3nlm1PZ} zsux}Xb7Ciz{N+#>z@;f^J!1)~_`)zN2XPjari@EH-^A>oy9i}OrG+U2h`=~B>qpL- zX${|#@U%I0peS_5PhNPa@-RWph9_m$(sr`LbZdHMX_pI8it#fSW8j!I&i>u>Nx9K= zMF_DL&tr1}n;C%Jj=&?j;Tlh#hHIDcK{XUuRdjppZo-XkP<+!Om0JQS6wl(vRt85H zcx6xnV`yE^8&{&yZe)@nkYyzjj?RmdsQDreaxo{E4w{mPhpXVok^+ntJe}| zK(~8bEW$&#O4&0L8@Hc=I^Ubs`CgKxy=g?Gz+KcY{Cz;B(oFUq{bPX)o2}Q+{p--# zUkY<*nMgDT;A2xamenro+)%V|YH!-{p(EPZV8-hGU{bAJK3r`I(A diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata.py b/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata.py deleted file mode 100644 index b13fbdef..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Metadata generation logic for source distributions. -""" - -import logging -import os - -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from pip._internal.build_env import BuildEnvironment - from pip._vendor.pep517.wrappers import Pep517HookCaller - -logger = logging.getLogger(__name__) - - -def generate_metadata(build_env, backend): - # type: (BuildEnvironment, Pep517HookCaller) -> str - """Generate metadata using mechanisms described in PEP 517. - - Returns the generated metadata directory. - """ - metadata_tmpdir = TempDirectory( - kind="modern-metadata", globally_managed=True - ) - - metadata_dir = metadata_tmpdir.path - - with build_env: - # Note that Pep517HookCaller implements a fallback for - # prepare_metadata_for_build_wheel, so we don't have to - # consider the possibility that this hook doesn't exist. - runner = runner_with_spinner_message("Preparing wheel metadata") - with backend.subprocess_runner(runner): - distinfo_dir = backend.prepare_metadata_for_build_wheel( - metadata_dir - ) - - return os.path.join(metadata_dir, distinfo_dir) diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py b/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py deleted file mode 100644 index 14762aef..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py +++ /dev/null @@ -1,77 +0,0 @@ -"""Metadata generation logic for legacy source distributions. -""" - -import logging -import os - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args -from pip._internal.utils.subprocess import call_subprocess -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from pip._internal.build_env import BuildEnvironment - -logger = logging.getLogger(__name__) - - -def _find_egg_info(directory): - # type: (str) -> str - """Find an .egg-info subdirectory in `directory`. - """ - filenames = [ - f for f in os.listdir(directory) if f.endswith(".egg-info") - ] - - if not filenames: - raise InstallationError( - "No .egg-info directory found in {}".format(directory) - ) - - if len(filenames) > 1: - raise InstallationError( - "More than one .egg-info directory found in {}".format( - directory - ) - ) - - return os.path.join(directory, filenames[0]) - - -def generate_metadata( - build_env, # type: BuildEnvironment - setup_py_path, # type: str - source_dir, # type: str - isolated, # type: bool - details, # type: str -): - # type: (...) -> str - """Generate metadata using setup.py-based defacto mechanisms. - - Returns the generated metadata directory. - """ - logger.debug( - 'Running setup.py (path:%s) egg_info for package %s', - setup_py_path, details, - ) - - egg_info_dir = TempDirectory( - kind="pip-egg-info", globally_managed=True - ).path - - args = make_setuptools_egg_info_args( - setup_py_path, - egg_info_dir=egg_info_dir, - no_user_config=isolated, - ) - - with build_env: - call_subprocess( - args, - cwd=source_dir, - command_desc='python setup.py egg_info', - ) - - # Return the .egg-info directory. - return _find_egg_info(egg_info_dir) diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel.py deleted file mode 100644 index 1266ce05..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel.py +++ /dev/null @@ -1,46 +0,0 @@ -import logging -import os - -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional - from pip._vendor.pep517.wrappers import Pep517HookCaller - -logger = logging.getLogger(__name__) - - -def build_wheel_pep517( - name, # type: str - backend, # type: Pep517HookCaller - metadata_directory, # type: str - build_options, # type: List[str] - tempd, # type: str -): - # type: (...) -> Optional[str] - """Build one InstallRequirement using the PEP 517 build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - assert metadata_directory is not None - if build_options: - # PEP 517 does not support --build-options - logger.error('Cannot build wheel for %s using PEP 517 when ' - '--build-option is present' % (name,)) - return None - try: - logger.debug('Destination directory: %s', tempd) - - runner = runner_with_spinner_message( - 'Building wheel for {} (PEP 517)'.format(name) - ) - with backend.subprocess_runner(runner): - wheel_name = backend.build_wheel( - tempd, - metadata_directory=metadata_directory, - ) - except Exception: - logger.error('Failed building wheel for %s', name) - return None - return os.path.join(tempd, wheel_name) diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel_legacy.py b/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel_legacy.py deleted file mode 100644 index 37dc876a..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/build/wheel_legacy.py +++ /dev/null @@ -1,115 +0,0 @@ -import logging -import os.path - -from pip._internal.cli.spinners import open_spinner -from pip._internal.utils.setuptools_build import ( - make_setuptools_bdist_wheel_args, -) -from pip._internal.utils.subprocess import ( - LOG_DIVIDER, - call_subprocess, - format_command_args, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Text - -logger = logging.getLogger(__name__) - - -def format_command_result( - command_args, # type: List[str] - command_output, # type: Text -): - # type: (...) -> str - """Format command information for logging.""" - command_desc = format_command_args(command_args) - text = 'Command arguments: {}\n'.format(command_desc) - - if not command_output: - text += 'Command output: None' - elif logger.getEffectiveLevel() > logging.DEBUG: - text += 'Command output: [use --verbose to show]' - else: - if not command_output.endswith('\n'): - command_output += '\n' - text += 'Command output:\n{}{}'.format(command_output, LOG_DIVIDER) - - return text - - -def get_legacy_build_wheel_path( - names, # type: List[str] - temp_dir, # type: str - name, # type: str - command_args, # type: List[str] - command_output, # type: Text -): - # type: (...) -> Optional[str] - """Return the path to the wheel in the temporary build directory.""" - # Sort for determinism. - names = sorted(names) - if not names: - msg = ( - 'Legacy build of wheel for {!r} created no files.\n' - ).format(name) - msg += format_command_result(command_args, command_output) - logger.warning(msg) - return None - - if len(names) > 1: - msg = ( - 'Legacy build of wheel for {!r} created more than one file.\n' - 'Filenames (choosing first): {}\n' - ).format(name, names) - msg += format_command_result(command_args, command_output) - logger.warning(msg) - - return os.path.join(temp_dir, names[0]) - - -def build_wheel_legacy( - name, # type: str - setup_py_path, # type: str - source_dir, # type: str - global_options, # type: List[str] - build_options, # type: List[str] - tempd, # type: str -): - # type: (...) -> Optional[str] - """Build one unpacked package using the "legacy" build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - wheel_args = make_setuptools_bdist_wheel_args( - setup_py_path, - global_options=global_options, - build_options=build_options, - destination_dir=tempd, - ) - - spin_message = 'Building wheel for {} (setup.py)'.format(name) - with open_spinner(spin_message) as spinner: - logger.debug('Destination directory: %s', tempd) - - try: - output = call_subprocess( - wheel_args, - cwd=source_dir, - spinner=spinner, - ) - except Exception: - spinner.finish("error") - logger.error('Failed building wheel for %s', name) - return None - - names = os.listdir(tempd) - wheel_path = get_legacy_build_wheel_path( - names=names, - temp_dir=tempd, - name=name, - command_args=wheel_args, - command_output=output, - ) - return wheel_path diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/check.py b/env/lib/python3.8/site-packages/pip/_internal/operations/check.py deleted file mode 100644 index b85a1230..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/check.py +++ /dev/null @@ -1,163 +0,0 @@ -"""Validation of dependencies of packages -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -import logging -from collections import namedtuple - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.pkg_resources import RequirementParseError - -from pip._internal.distributions import ( - make_distribution_for_install_requirement, -) -from pip._internal.utils.misc import get_installed_distributions -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -logger = logging.getLogger(__name__) - -if MYPY_CHECK_RUNNING: - from pip._internal.req.req_install import InstallRequirement - from typing import ( - Any, Callable, Dict, Optional, Set, Tuple, List - ) - - # Shorthands - PackageSet = Dict[str, 'PackageDetails'] - Missing = Tuple[str, Any] - Conflicting = Tuple[str, str, Any] - - MissingDict = Dict[str, List[Missing]] - ConflictingDict = Dict[str, List[Conflicting]] - CheckResult = Tuple[MissingDict, ConflictingDict] - -PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) - - -def create_package_set_from_installed(**kwargs): - # type: (**Any) -> Tuple[PackageSet, bool] - """Converts a list of distributions into a PackageSet. - """ - # Default to using all packages installed on the system - if kwargs == {}: - kwargs = {"local_only": False, "skip": ()} - - package_set = {} - problems = False - for dist in get_installed_distributions(**kwargs): - name = canonicalize_name(dist.project_name) - try: - package_set[name] = PackageDetails(dist.version, dist.requires()) - except RequirementParseError as e: - # Don't crash on broken metadata - logger.warning("Error parsing requirements for %s: %s", name, e) - problems = True - return package_set, problems - - -def check_package_set(package_set, should_ignore=None): - # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult - """Check if a package set is consistent - - If should_ignore is passed, it should be a callable that takes a - package name and returns a boolean. - """ - if should_ignore is None: - def should_ignore(name): - return False - - missing = {} - conflicting = {} - - for package_name in package_set: - # Info about dependencies of package_name - missing_deps = set() # type: Set[Missing] - conflicting_deps = set() # type: Set[Conflicting] - - if should_ignore(package_name): - continue - - for req in package_set[package_name].requires: - name = canonicalize_name(req.project_name) # type: str - - # Check if it's missing - if name not in package_set: - missed = True - if req.marker is not None: - missed = req.marker.evaluate() - if missed: - missing_deps.add((name, req)) - continue - - # Check if there's a conflict - version = package_set[name].version # type: str - if not req.specifier.contains(version, prereleases=True): - conflicting_deps.add((name, version, req)) - - if missing_deps: - missing[package_name] = sorted(missing_deps, key=str) - if conflicting_deps: - conflicting[package_name] = sorted(conflicting_deps, key=str) - - return missing, conflicting - - -def check_install_conflicts(to_install): - # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] - """For checking if the dependency graph would be consistent after \ - installing given requirements - """ - # Start from the current state - package_set, _ = create_package_set_from_installed() - # Install packages - would_be_installed = _simulate_installation_of(to_install, package_set) - - # Only warn about directly-dependent packages; create a whitelist of them - whitelist = _create_whitelist(would_be_installed, package_set) - - return ( - package_set, - check_package_set( - package_set, should_ignore=lambda name: name not in whitelist - ) - ) - - -def _simulate_installation_of(to_install, package_set): - # type: (List[InstallRequirement], PackageSet) -> Set[str] - """Computes the version of packages after installing to_install. - """ - - # Keep track of packages that were installed - installed = set() - - # Modify it as installing requirement_set would (assuming no errors) - for inst_req in to_install: - abstract_dist = make_distribution_for_install_requirement(inst_req) - dist = abstract_dist.get_pkg_resources_distribution() - - name = canonicalize_name(dist.key) - package_set[name] = PackageDetails(dist.version, dist.requires()) - - installed.add(name) - - return installed - - -def _create_whitelist(would_be_installed, package_set): - # type: (Set[str], PackageSet) -> Set[str] - packages_affected = set(would_be_installed) - - for package_name in package_set: - if package_name in packages_affected: - continue - - for req in package_set[package_name].requires: - if canonicalize_name(req.name) in packages_affected: - packages_affected.add(package_name) - break - - return packages_affected diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/freeze.py b/env/lib/python3.8/site-packages/pip/_internal/operations/freeze.py deleted file mode 100644 index aa6b052b..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/freeze.py +++ /dev/null @@ -1,272 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import collections -import logging -import os - -from pip._vendor import six -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.pkg_resources import RequirementParseError - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.req.constructors import ( - install_req_from_editable, - install_req_from_line, -) -from pip._internal.req.req_file import COMMENT_RE -from pip._internal.utils.direct_url_helpers import ( - direct_url_as_pep440_direct_reference, - dist_get_direct_url, -) -from pip._internal.utils.misc import ( - dist_is_editable, - get_installed_distributions, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Iterator, Optional, List, Container, Set, Dict, Tuple, Iterable, Union - ) - from pip._internal.cache import WheelCache - from pip._vendor.pkg_resources import ( - Distribution, Requirement - ) - - RequirementInfo = Tuple[Optional[Union[str, Requirement]], bool, List[str]] - - -logger = logging.getLogger(__name__) - - -def freeze( - requirement=None, # type: Optional[List[str]] - find_links=None, # type: Optional[List[str]] - local_only=None, # type: Optional[bool] - user_only=None, # type: Optional[bool] - paths=None, # type: Optional[List[str]] - isolated=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - exclude_editable=False, # type: bool - skip=() # type: Container[str] -): - # type: (...) -> Iterator[str] - find_links = find_links or [] - - for link in find_links: - yield '-f {}'.format(link) - installations = {} # type: Dict[str, FrozenRequirement] - for dist in get_installed_distributions(local_only=local_only, - skip=(), - user_only=user_only, - paths=paths): - try: - req = FrozenRequirement.from_dist(dist) - except RequirementParseError as exc: - # We include dist rather than dist.project_name because the - # dist string includes more information, like the version and - # location. We also include the exception message to aid - # troubleshooting. - logger.warning( - 'Could not generate requirement for distribution %r: %s', - dist, exc - ) - continue - if exclude_editable and req.editable: - continue - installations[req.canonical_name] = req - - if requirement: - # the options that don't get turned into an InstallRequirement - # should only be emitted once, even if the same option is in multiple - # requirements files, so we need to keep track of what has been emitted - # so that we don't emit it again if it's seen again - emitted_options = set() # type: Set[str] - # keep track of which files a requirement is in so that we can - # give an accurate warning if a requirement appears multiple times. - req_files = collections.defaultdict(list) # type: Dict[str, List[str]] - for req_file_path in requirement: - with open(req_file_path) as req_file: - for line in req_file: - if (not line.strip() or - line.strip().startswith('#') or - line.startswith(( - '-r', '--requirement', - '-Z', '--always-unzip', - '-f', '--find-links', - '-i', '--index-url', - '--pre', - '--trusted-host', - '--process-dependency-links', - '--extra-index-url'))): - line = line.rstrip() - if line not in emitted_options: - emitted_options.add(line) - yield line - continue - - if line.startswith('-e') or line.startswith('--editable'): - if line.startswith('-e'): - line = line[2:].strip() - else: - line = line[len('--editable'):].strip().lstrip('=') - line_req = install_req_from_editable( - line, - isolated=isolated, - ) - else: - line_req = install_req_from_line( - COMMENT_RE.sub('', line).strip(), - isolated=isolated, - ) - - if not line_req.name: - logger.info( - "Skipping line in requirement file [%s] because " - "it's not clear what it would install: %s", - req_file_path, line.strip(), - ) - logger.info( - " (add #egg=PackageName to the URL to avoid" - " this warning)" - ) - else: - line_req_canonical_name = canonicalize_name( - line_req.name) - if line_req_canonical_name not in installations: - # either it's not installed, or it is installed - # but has been processed already - if not req_files[line_req.name]: - logger.warning( - "Requirement file [%s] contains %s, but " - "package %r is not installed", - req_file_path, - COMMENT_RE.sub('', line).strip(), - line_req.name - ) - else: - req_files[line_req.name].append(req_file_path) - else: - yield str(installations[ - line_req_canonical_name]).rstrip() - del installations[line_req_canonical_name] - req_files[line_req.name].append(req_file_path) - - # Warn about requirements that were included multiple times (in a - # single requirements file or in different requirements files). - for name, files in six.iteritems(req_files): - if len(files) > 1: - logger.warning("Requirement %s included multiple times [%s]", - name, ', '.join(sorted(set(files)))) - - yield( - '## The following requirements were added by ' - 'pip freeze:' - ) - for installation in sorted( - installations.values(), key=lambda x: x.name.lower()): - if installation.canonical_name not in skip: - yield str(installation).rstrip() - - -def get_requirement_info(dist): - # type: (Distribution) -> RequirementInfo - """ - Compute and return values (req, editable, comments) for use in - FrozenRequirement.from_dist(). - """ - if not dist_is_editable(dist): - return (None, False, []) - - location = os.path.normcase(os.path.abspath(dist.location)) - - from pip._internal.vcs import vcs, RemoteNotFoundError - vcs_backend = vcs.get_backend_for_dir(location) - - if vcs_backend is None: - req = dist.as_requirement() - logger.debug( - 'No VCS found for editable requirement "%s" in: %r', req, - location, - ) - comments = [ - '# Editable install with no version control ({})'.format(req) - ] - return (location, True, comments) - - try: - req = vcs_backend.get_src_requirement(location, dist.project_name) - except RemoteNotFoundError: - req = dist.as_requirement() - comments = [ - '# Editable {} install with no remote ({})'.format( - type(vcs_backend).__name__, req, - ) - ] - return (location, True, comments) - - except BadCommand: - logger.warning( - 'cannot determine version of editable source in %s ' - '(%s command not found in path)', - location, - vcs_backend.name, - ) - return (None, True, []) - - except InstallationError as exc: - logger.warning( - "Error when trying to get requirement for VCS system %s, " - "falling back to uneditable format", exc - ) - else: - if req is not None: - return (req, True, []) - - logger.warning( - 'Could not determine repository location of %s', location - ) - comments = ['## !! Could not determine repository location'] - - return (None, False, comments) - - -class FrozenRequirement(object): - def __init__(self, name, req, editable, comments=()): - # type: (str, Union[str, Requirement], bool, Iterable[str]) -> None - self.name = name - self.canonical_name = canonicalize_name(name) - self.req = req - self.editable = editable - self.comments = comments - - @classmethod - def from_dist(cls, dist): - # type: (Distribution) -> FrozenRequirement - # TODO `get_requirement_info` is taking care of editable requirements. - # TODO This should be refactored when we will add detection of - # editable that provide .dist-info metadata. - req, editable, comments = get_requirement_info(dist) - if req is None and not editable: - # if PEP 610 metadata is present, attempt to use it - direct_url = dist_get_direct_url(dist) - if direct_url: - req = direct_url_as_pep440_direct_reference( - direct_url, dist.project_name - ) - comments = [] - if req is None: - # name==version requirement - req = dist.as_requirement() - - return cls(dist.project_name, req, editable, comments=comments) - - def __str__(self): - req = self.req - if self.editable: - req = '-e {}'.format(req) - return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/install/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/operations/install/__init__.py deleted file mode 100644 index 24d6a5dd..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/install/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""For modules related to installing packages. -""" diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 4ca530e03f172dade252feb218a36d52830a7a71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 22b4ff1eeda64cc55d3a8bb4269c9f2d21efd4d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15071 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 None - """Install a package in editable mode. Most arguments are pass-through - to setuptools. - """ - logger.info('Running setup.py develop for %s', name) - - args = make_setuptools_develop_args( - setup_py_path, - global_options=global_options, - install_options=install_options, - no_user_config=isolated, - prefix=prefix, - home=home, - use_user_site=use_user_site, - ) - - with indent_log(): - with build_env: - call_subprocess( - args, - cwd=unpacked_source_directory, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py b/env/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py deleted file mode 100644 index 0fac9057..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Legacy installation process, i.e. `setup.py install`. -""" - -import logging -import os -import sys -from distutils.util import change_root - -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ensure_dir -from pip._internal.utils.setuptools_build import make_setuptools_install_args -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Sequence - - from pip._internal.build_env import BuildEnvironment - from pip._internal.models.scheme import Scheme - - -logger = logging.getLogger(__name__) - - -class LegacyInstallFailure(Exception): - def __init__(self): - # type: () -> None - self.parent = sys.exc_info() - - -def install( - install_options, # type: List[str] - global_options, # type: Sequence[str] - root, # type: Optional[str] - home, # type: Optional[str] - prefix, # type: Optional[str] - use_user_site, # type: bool - pycompile, # type: bool - scheme, # type: Scheme - setup_py_path, # type: str - isolated, # type: bool - req_name, # type: str - build_env, # type: BuildEnvironment - unpacked_source_directory, # type: str - req_description, # type: str -): - # type: (...) -> bool - - header_dir = scheme.headers - - with TempDirectory(kind="record") as temp_dir: - try: - record_filename = os.path.join(temp_dir.path, 'install-record.txt') - install_args = make_setuptools_install_args( - setup_py_path, - global_options=global_options, - install_options=install_options, - record_filename=record_filename, - root=root, - prefix=prefix, - header_dir=header_dir, - home=home, - use_user_site=use_user_site, - no_user_config=isolated, - pycompile=pycompile, - ) - - runner = runner_with_spinner_message( - "Running setup.py install for {}".format(req_name) - ) - with indent_log(), build_env: - runner( - cmd=install_args, - cwd=unpacked_source_directory, - ) - - if not os.path.exists(record_filename): - logger.debug('Record file %s not found', record_filename) - # Signal to the caller that we didn't install the new package - return False - - except Exception: - # Signal to the caller that we didn't install the new package - raise LegacyInstallFailure - - # At this point, we have successfully installed the requirement. - - # We intentionally do not use any encoding to read the file because - # setuptools writes the file using distutils.file_util.write_file, - # which does not specify an encoding. - with open(record_filename) as f: - record_lines = f.read().splitlines() - - def prepend_root(path): - # type: (str) -> str - if root is None or not os.path.isabs(path): - return path - else: - return change_root(root, path) - - for line in record_lines: - directory = os.path.dirname(line) - if directory.endswith('.egg-info'): - egg_info_dir = prepend_root(directory) - break - else: - deprecated( - reason=( - "{} did not indicate that it installed an " - ".egg-info directory. Only setup.py projects " - "generating .egg-info directories are supported." - ).format(req_description), - replacement=( - "for maintainers: updating the setup.py of {0}. " - "For users: contact the maintainers of {0} to let " - "them know to update their setup.py.".format( - req_name - ) - ), - gone_in="20.2", - issue=6998, - ) - # FIXME: put the record somewhere - return True - - new_lines = [] - for line in record_lines: - filename = line.strip() - if os.path.isdir(filename): - filename += os.path.sep - new_lines.append( - os.path.relpath(prepend_root(filename), egg_info_dir) - ) - new_lines.sort() - ensure_dir(egg_info_dir) - inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') - with open(inst_files_path, 'w') as f: - f.write('\n'.join(new_lines) + '\n') - - return True diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py deleted file mode 100644 index 2fb86b86..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py +++ /dev/null @@ -1,631 +0,0 @@ -"""Support for installing and building the "wheel" binary package format. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import collections -import compileall -import contextlib -import csv -import logging -import os.path -import re -import shutil -import stat -import sys -import warnings -from base64 import urlsafe_b64encode -from itertools import starmap -from zipfile import ZipFile - -from pip._vendor import pkg_resources -from pip._vendor.distlib.scripts import ScriptMaker -from pip._vendor.distlib.util import get_export_entry -from pip._vendor.six import StringIO - -from pip._internal.exceptions import InstallationError -from pip._internal.locations import get_major_minor_version -from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl -from pip._internal.utils.filesystem import adjacent_tmp_file, replace -from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.unpacking import current_umask, unpack_file -from pip._internal.utils.wheel import parse_wheel - -if MYPY_CHECK_RUNNING: - from email.message import Message - from typing import ( - Dict, List, Optional, Sequence, Tuple, Any, - Iterable, Iterator, Callable, Set, - ) - - from pip._internal.models.scheme import Scheme - from pip._internal.utils.filesystem import NamedTemporaryFileResult - - InstalledCSVRow = Tuple[str, ...] - - -logger = logging.getLogger(__name__) - - -def normpath(src, p): - # type: (str, str) -> str - return os.path.relpath(src, p).replace(os.path.sep, '/') - - -def rehash(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[str, str] - """Return (encoded_digest, length) for path using hashlib.sha256()""" - h, length = hash_file(path, blocksize) - digest = 'sha256=' + urlsafe_b64encode( - h.digest() - ).decode('latin1').rstrip('=') - # unicode/str python2 issues - return (digest, str(length)) # type: ignore - - -def csv_io_kwargs(mode): - # type: (str) -> Dict[str, Any] - """Return keyword arguments to properly open a CSV file - in the given mode. - """ - if sys.version_info.major < 3: - return {'mode': '{}b'.format(mode)} - else: - return {'mode': mode, 'newline': ''} - - -def fix_script(path): - # type: (str) -> Optional[bool] - """Replace #!python with #!/path/to/python - Return True if file was changed. - """ - # XXX RECORD hashes will need to be updated - if os.path.isfile(path): - with open(path, 'rb') as script: - firstline = script.readline() - if not firstline.startswith(b'#!python'): - return False - exename = sys.executable.encode(sys.getfilesystemencoding()) - firstline = b'#!' + exename + os.linesep.encode("ascii") - rest = script.read() - with open(path, 'wb') as script: - script.write(firstline) - script.write(rest) - return True - return None - - -def wheel_root_is_purelib(metadata): - # type: (Message) -> bool - return metadata.get("Root-Is-Purelib", "").lower() == "true" - - -def get_entrypoints(filename): - # type: (str) -> Tuple[Dict[str, str], Dict[str, str]] - if not os.path.exists(filename): - return {}, {} - - # This is done because you can pass a string to entry_points wrappers which - # means that they may or may not be valid INI files. The attempt here is to - # strip leading and trailing whitespace in order to make them valid INI - # files. - with open(filename) as fp: - data = StringIO() - for line in fp: - data.write(line.strip()) - data.write("\n") - data.seek(0) - - # get the entry points and then the script names - entry_points = pkg_resources.EntryPoint.parse_map(data) - console = entry_points.get('console_scripts', {}) - gui = entry_points.get('gui_scripts', {}) - - def _split_ep(s): - # type: (pkg_resources.EntryPoint) -> Tuple[str, str] - """get the string representation of EntryPoint, - remove space and split on '=' - """ - split_parts = str(s).replace(" ", "").split("=") - return split_parts[0], split_parts[1] - - # convert the EntryPoint objects into strings with module:function - console = dict(_split_ep(v) for v in console.values()) - gui = dict(_split_ep(v) for v in gui.values()) - return console, gui - - -def message_about_scripts_not_on_PATH(scripts): - # type: (Sequence[str]) -> Optional[str] - """Determine if any scripts are not on PATH and format a warning. - Returns a warning message if one or more scripts are not on PATH, - otherwise None. - """ - if not scripts: - return None - - # Group scripts by the path they were installed in - grouped_by_dir = collections.defaultdict(set) # type: Dict[str, Set[str]] - for destfile in scripts: - parent_dir = os.path.dirname(destfile) - script_name = os.path.basename(destfile) - grouped_by_dir[parent_dir].add(script_name) - - # We don't want to warn for directories that are on PATH. - not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) for i in - os.environ.get("PATH", "").split(os.pathsep) - ] - # If an executable sits with sys.executable, we don't warn for it. - # This covers the case of venv invocations without activating the venv. - not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) - warn_for = { - parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() - if os.path.normcase(parent_dir) not in not_warn_dirs - } # type: Dict[str, Set[str]] - if not warn_for: - return None - - # Format a message - msg_lines = [] - for parent_dir, dir_scripts in warn_for.items(): - sorted_scripts = sorted(dir_scripts) # type: List[str] - if len(sorted_scripts) == 1: - start_text = "script {} is".format(sorted_scripts[0]) - else: - start_text = "scripts {} are".format( - ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] - ) - - msg_lines.append( - "The {} installed in '{}' which is not on PATH." - .format(start_text, parent_dir) - ) - - last_line_fmt = ( - "Consider adding {} to PATH or, if you prefer " - "to suppress this warning, use --no-warn-script-location." - ) - if len(msg_lines) == 1: - msg_lines.append(last_line_fmt.format("this directory")) - else: - msg_lines.append(last_line_fmt.format("these directories")) - - # Add a note if any directory starts with ~ - warn_for_tilde = any( - i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i - ) - if warn_for_tilde: - tilde_warning_msg = ( - "NOTE: The current PATH contains path(s) starting with `~`, " - "which may not be expanded by all applications." - ) - msg_lines.append(tilde_warning_msg) - - # Returns the formatted multiline message - return "\n".join(msg_lines) - - -def sorted_outrows(outrows): - # type: (Iterable[InstalledCSVRow]) -> List[InstalledCSVRow] - """Return the given rows of a RECORD file in sorted order. - - Each row is a 3-tuple (path, hash, size) and corresponds to a record of - a RECORD file (see PEP 376 and PEP 427 for details). For the rows - passed to this function, the size can be an integer as an int or string, - or the empty string. - """ - # Normally, there should only be one row per path, in which case the - # second and third elements don't come into play when sorting. - # However, in cases in the wild where a path might happen to occur twice, - # we don't want the sort operation to trigger an error (but still want - # determinism). Since the third element can be an int or string, we - # coerce each element to a string to avoid a TypeError in this case. - # For additional background, see-- - # https://github.com/pypa/pip/issues/5868 - return sorted(outrows, key=lambda row: tuple(str(x) for x in row)) - - -def get_csv_rows_for_installed( - old_csv_rows, # type: Iterable[List[str]] - installed, # type: Dict[str, str] - changed, # type: Set[str] - generated, # type: List[str] - lib_dir, # type: str -): - # type: (...) -> List[InstalledCSVRow] - """ - :param installed: A map from archive RECORD path to installation RECORD - path. - """ - installed_rows = [] # type: List[InstalledCSVRow] - for row in old_csv_rows: - if len(row) > 3: - logger.warning( - 'RECORD line has more than three elements: {}'.format(row) - ) - # Make a copy because we are mutating the row. - row = list(row) - old_path = row[0] - new_path = installed.pop(old_path, old_path) - row[0] = new_path - if new_path in changed: - digest, length = rehash(new_path) - row[1] = digest - row[2] = length - installed_rows.append(tuple(row)) - for f in generated: - digest, length = rehash(f) - installed_rows.append((normpath(f, lib_dir), digest, str(length))) - for f in installed: - installed_rows.append((installed[f], '', '')) - return installed_rows - - -class MissingCallableSuffix(Exception): - pass - - -def _raise_for_invalid_entrypoint(specification): - # type: (str) -> None - entry = get_export_entry(specification) - if entry is not None and entry.suffix is None: - raise MissingCallableSuffix(str(entry)) - - -class PipScriptMaker(ScriptMaker): - def make(self, specification, options=None): - # type: (str, Dict[str, Any]) -> List[str] - _raise_for_invalid_entrypoint(specification) - return super(PipScriptMaker, self).make(specification, options) - - -def install_unpacked_wheel( - name, # type: str - wheeldir, # type: str - wheel_zip, # type: ZipFile - scheme, # type: Scheme - req_description, # type: str - pycompile=True, # type: bool - warn_script_location=True, # type: bool - direct_url=None, # type: Optional[DirectUrl] -): - # type: (...) -> None - """Install a wheel. - - :param name: Name of the project to install - :param wheeldir: Base directory of the unpacked wheel - :param wheel_zip: open ZipFile for wheel being installed - :param scheme: Distutils scheme dictating the install directories - :param req_description: String used in place of the requirement, for - logging - :param pycompile: Whether to byte-compile installed Python files - :param warn_script_location: Whether to check that scripts are installed - into a directory on PATH - :raises UnsupportedWheel: - * when the directory holds an unpacked wheel with incompatible - Wheel-Version - * when the .dist-info dir does not match the wheel - """ - # TODO: Investigate and break this up. - # TODO: Look into moving this into a dedicated class for representing an - # installation. - - source = wheeldir.rstrip(os.path.sep) + os.path.sep - - info_dir, metadata = parse_wheel(wheel_zip, name) - - if wheel_root_is_purelib(metadata): - lib_dir = scheme.purelib - else: - lib_dir = scheme.platlib - - subdirs = os.listdir(source) - data_dirs = [s for s in subdirs if s.endswith('.data')] - - # Record details of the files moved - # installed = files copied from the wheel to the destination - # changed = files changed while installing (scripts #! line typically) - # generated = files newly generated during the install (script wrappers) - installed = {} # type: Dict[str, str] - changed = set() - generated = [] # type: List[str] - - # Compile all of the pyc files that we're going to be installing - if pycompile: - with captured_stdout() as stdout: - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - compileall.compile_dir(source, force=True, quiet=True) - logger.debug(stdout.getvalue()) - - def record_installed(srcfile, destfile, modified=False): - # type: (str, str, bool) -> None - """Map archive RECORD paths to installation RECORD paths.""" - oldpath = normpath(srcfile, wheeldir) - newpath = normpath(destfile, lib_dir) - installed[oldpath] = newpath - if modified: - changed.add(destfile) - - def clobber( - source, # type: str - dest, # type: str - is_base, # type: bool - fixer=None, # type: Optional[Callable[[str], Any]] - filter=None # type: Optional[Callable[[str], bool]] - ): - # type: (...) -> None - ensure_dir(dest) # common for the 'include' path - - for dir, subdirs, files in os.walk(source): - basedir = dir[len(source):].lstrip(os.path.sep) - destdir = os.path.join(dest, basedir) - if is_base and basedir == '': - subdirs[:] = [s for s in subdirs if not s.endswith('.data')] - for f in files: - # Skip unwanted files - if filter and filter(f): - continue - srcfile = os.path.join(dir, f) - destfile = os.path.join(dest, basedir, f) - # directory creation is lazy and after the file filtering above - # to ensure we don't install empty dirs; empty dirs can't be - # uninstalled. - ensure_dir(destdir) - - # copyfile (called below) truncates the destination if it - # exists and then writes the new contents. This is fine in most - # cases, but can cause a segfault if pip has loaded a shared - # object (e.g. from pyopenssl through its vendored urllib3) - # Since the shared object is mmap'd an attempt to call a - # symbol in it will then cause a segfault. Unlinking the file - # allows writing of new contents while allowing the process to - # continue to use the old copy. - if os.path.exists(destfile): - os.unlink(destfile) - - # We use copyfile (not move, copy, or copy2) to be extra sure - # that we are not moving directories over (copyfile fails for - # directories) as well as to ensure that we are not copying - # over any metadata because we want more control over what - # metadata we actually copy over. - shutil.copyfile(srcfile, destfile) - - # Copy over the metadata for the file, currently this only - # includes the atime and mtime. - st = os.stat(srcfile) - if hasattr(os, "utime"): - os.utime(destfile, (st.st_atime, st.st_mtime)) - - # If our file is executable, then make our destination file - # executable. - if os.access(srcfile, os.X_OK): - st = os.stat(srcfile) - permissions = ( - st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - ) - os.chmod(destfile, permissions) - - changed = False - if fixer: - changed = fixer(destfile) - record_installed(srcfile, destfile, changed) - - clobber(source, lib_dir, True) - - dest_info_dir = os.path.join(lib_dir, info_dir) - - # Get the defined entry points - ep_file = os.path.join(dest_info_dir, 'entry_points.txt') - console, gui = get_entrypoints(ep_file) - - def is_entrypoint_wrapper(name): - # type: (str) -> bool - # EP, EP.exe and EP-script.py are scripts generated for - # entry point EP by setuptools - if name.lower().endswith('.exe'): - matchname = name[:-4] - elif name.lower().endswith('-script.py'): - matchname = name[:-10] - elif name.lower().endswith(".pya"): - matchname = name[:-4] - else: - matchname = name - # Ignore setuptools-generated scripts - return (matchname in console or matchname in gui) - - for datadir in data_dirs: - fixer = None - filter = None - for subdir in os.listdir(os.path.join(wheeldir, datadir)): - fixer = None - if subdir == 'scripts': - fixer = fix_script - filter = is_entrypoint_wrapper - source = os.path.join(wheeldir, datadir, subdir) - dest = getattr(scheme, subdir) - clobber(source, dest, False, fixer=fixer, filter=filter) - - maker = PipScriptMaker(None, scheme.scripts) - - # Ensure old scripts are overwritten. - # See https://github.com/pypa/pip/issues/1800 - maker.clobber = True - - # Ensure we don't generate any variants for scripts because this is almost - # never what somebody wants. - # See https://bitbucket.org/pypa/distlib/issue/35/ - maker.variants = {''} - - # This is required because otherwise distlib creates scripts that are not - # executable. - # See https://bitbucket.org/pypa/distlib/issue/32/ - maker.set_mode = True - - scripts_to_generate = [] - - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points, but that won't happen till Metadata 2.0 is - # available. - # In the meantime, projects using versioned entry points will either have - # incorrect versioned entry points, or they will not be able to distribute - # "universal" wheels (i.e., they will need a wheel per Python version). - # - # Because setuptools and pip are bundled with _ensurepip and virtualenv, - # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we - # override the versioned entry points in the wheel and generate the - # correct ones. This code is purely a short-term measure until Metadata 2.0 - # is available. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop('pip', None) - if pip_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append('pip = ' + pip_script) - - if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - scripts_to_generate.append( - 'pip{} = {}'.format(sys.version_info[0], pip_script) - ) - - scripts_to_generate.append( - 'pip{} = {}'.format(get_major_minor_version(), pip_script) - ) - # Delete any other versioned pip entry points - pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] - for k in pip_ep: - del console[k] - easy_install_script = console.pop('easy_install', None) - if easy_install_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append( - 'easy_install = ' + easy_install_script - ) - - scripts_to_generate.append( - 'easy_install-{} = {}'.format( - get_major_minor_version(), easy_install_script - ) - ) - # Delete any other versioned easy_install entry points - easy_install_ep = [ - k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) - ] - for k in easy_install_ep: - del console[k] - - # Generate the console and GUI entry points specified in the wheel - scripts_to_generate.extend(starmap('{} = {}'.format, console.items())) - - gui_scripts_to_generate = list(starmap('{} = {}'.format, gui.items())) - - generated_console_scripts = [] # type: List[str] - - try: - generated_console_scripts = maker.make_multiple(scripts_to_generate) - generated.extend(generated_console_scripts) - - generated.extend( - maker.make_multiple(gui_scripts_to_generate, {'gui': True}) - ) - except MissingCallableSuffix as e: - entry = e.args[0] - raise InstallationError( - "Invalid script entry point: {} for req: {} - A callable " - "suffix is required. Cf https://packaging.python.org/" - "specifications/entry-points/#use-for-scripts for more " - "information.".format(entry, req_description) - ) - - if warn_script_location: - msg = message_about_scripts_not_on_PATH(generated_console_scripts) - if msg is not None: - logger.warning(msg) - - generated_file_mode = 0o666 & ~current_umask() - - @contextlib.contextmanager - def _generate_file(path, **kwargs): - # type: (str, **Any) -> Iterator[NamedTemporaryFileResult] - with adjacent_tmp_file(path, **kwargs) as f: - yield f - os.chmod(f.name, generated_file_mode) - replace(f.name, path) - - # Record pip as the installer - installer_path = os.path.join(dest_info_dir, 'INSTALLER') - with _generate_file(installer_path) as installer_file: - installer_file.write(b'pip\n') - generated.append(installer_path) - - # Record the PEP 610 direct URL reference - if direct_url is not None: - direct_url_path = os.path.join(dest_info_dir, DIRECT_URL_METADATA_NAME) - with _generate_file(direct_url_path) as direct_url_file: - direct_url_file.write(direct_url.to_json().encode("utf-8")) - generated.append(direct_url_path) - - # Record details of all files installed - record_path = os.path.join(dest_info_dir, 'RECORD') - with open(record_path, **csv_io_kwargs('r')) as record_file: - rows = get_csv_rows_for_installed( - csv.reader(record_file), - installed=installed, - changed=changed, - generated=generated, - lib_dir=lib_dir) - with _generate_file(record_path, **csv_io_kwargs('w')) as record_file: - writer = csv.writer(record_file) - writer.writerows(sorted_outrows(rows)) # sort to simplify testing - - -def install_wheel( - name, # type: str - wheel_path, # type: str - scheme, # type: Scheme - req_description, # type: str - pycompile=True, # type: bool - warn_script_location=True, # type: bool - _temp_dir_for_testing=None, # type: Optional[str] - direct_url=None, # type: Optional[DirectUrl] -): - # type: (...) -> None - with TempDirectory( - path=_temp_dir_for_testing, kind="unpacked-wheel" - ) as unpacked_dir, ZipFile(wheel_path, allowZip64=True) as z: - unpack_file(wheel_path, unpacked_dir.path) - install_unpacked_wheel( - name=name, - wheeldir=unpacked_dir.path, - wheel_zip=z, - scheme=scheme, - req_description=req_description, - pycompile=pycompile, - warn_script_location=warn_script_location, - direct_url=direct_url, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/operations/prepare.py b/env/lib/python3.8/site-packages/pip/_internal/operations/prepare.py deleted file mode 100644 index 1fcbb775..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/operations/prepare.py +++ /dev/null @@ -1,568 +0,0 @@ -"""Prepares a distribution for installation -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import logging -import mimetypes -import os -import shutil - -from pip._vendor import requests -from pip._vendor.six import PY2 - -from pip._internal.distributions import ( - make_distribution_for_install_requirement, -) -from pip._internal.distributions.installed import InstalledDistribution -from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, - HashMismatch, - HashUnpinned, - InstallationError, - PreviousBuildDirError, - VcsHashUnsupported, -) -from pip._internal.utils.filesystem import copy2_fixed -from pip._internal.utils.hashes import MissingHashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - display_path, - hide_url, - path_to_display, - rmtree, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.unpacking import unpack_file -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Callable, List, Optional, Tuple, - ) - - from mypy_extensions import TypedDict - - from pip._internal.distributions import AbstractDistribution - from pip._internal.index.package_finder import PackageFinder - from pip._internal.models.link import Link - from pip._internal.network.download import Downloader - from pip._internal.req.req_install import InstallRequirement - from pip._internal.req.req_tracker import RequirementTracker - from pip._internal.utils.hashes import Hashes - - if PY2: - CopytreeKwargs = TypedDict( - 'CopytreeKwargs', - { - 'ignore': Callable[[str, List[str]], List[str]], - 'symlinks': bool, - }, - total=False, - ) - else: - CopytreeKwargs = TypedDict( - 'CopytreeKwargs', - { - 'copy_function': Callable[[str, str], None], - 'ignore': Callable[[str, List[str]], List[str]], - 'ignore_dangling_symlinks': bool, - 'symlinks': bool, - }, - total=False, - ) - -logger = logging.getLogger(__name__) - - -def _get_prepared_distribution( - req, # type: InstallRequirement - req_tracker, # type: RequirementTracker - finder, # type: PackageFinder - build_isolation # type: bool -): - # type: (...) -> AbstractDistribution - """Prepare a distribution for installation. - """ - abstract_dist = make_distribution_for_install_requirement(req) - with req_tracker.track(req): - abstract_dist.prepare_distribution_metadata(finder, build_isolation) - return abstract_dist - - -def unpack_vcs_link(link, location): - # type: (Link, str) -> None - vcs_backend = vcs.get_backend_for_scheme(link.scheme) - assert vcs_backend is not None - vcs_backend.unpack(location, url=hide_url(link.url)) - - -class File(object): - def __init__(self, path, content_type): - # type: (str, str) -> None - self.path = path - self.content_type = content_type - - -def get_http_url( - link, # type: Link - downloader, # type: Downloader - download_dir=None, # type: Optional[str] - hashes=None, # type: Optional[Hashes] -): - # type: (...) -> File - temp_dir = TempDirectory(kind="unpack", globally_managed=True) - # If a download dir is specified, is the file already downloaded there? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir( - link, download_dir, hashes - ) - - if already_downloaded_path: - from_path = already_downloaded_path - content_type = mimetypes.guess_type(from_path)[0] - else: - # let's download to a tmp dir - from_path, content_type = _download_http_url( - link, downloader, temp_dir.path, hashes - ) - - return File(from_path, content_type) - - -def _copy2_ignoring_special_files(src, dest): - # type: (str, str) -> None - """Copying special files is not supported, but as a convenience to users - we skip errors copying them. This supports tools that may create e.g. - socket files in the project source directory. - """ - try: - copy2_fixed(src, dest) - except shutil.SpecialFileError as e: - # SpecialFileError may be raised due to either the source or - # destination. If the destination was the cause then we would actually - # care, but since the destination directory is deleted prior to - # copy we ignore all of them assuming it is caused by the source. - logger.warning( - "Ignoring special file error '%s' encountered copying %s to %s.", - str(e), - path_to_display(src), - path_to_display(dest), - ) - - -def _copy_source_tree(source, target): - # type: (str, str) -> None - target_abspath = os.path.abspath(target) - target_basename = os.path.basename(target_abspath) - target_dirname = os.path.dirname(target_abspath) - - def ignore(d, names): - # type: (str, List[str]) -> List[str] - skipped = [] # type: List[str] - if d == source: - # Pulling in those directories can potentially be very slow, - # exclude the following directories if they appear in the top - # level dir (and only it). - # See discussion at https://github.com/pypa/pip/pull/6770 - skipped += ['.tox', '.nox'] - if os.path.abspath(d) == target_dirname: - # Prevent an infinite recursion if the target is in source. - # This can happen when TMPDIR is set to ${PWD}/... - # and we copy PWD to TMPDIR. - skipped += [target_basename] - return skipped - - kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs - - if not PY2: - # Python 2 does not support copy_function, so we only ignore - # errors on special file copy in Python 3. - kwargs['copy_function'] = _copy2_ignoring_special_files - - shutil.copytree(source, target, **kwargs) - - -def get_file_url( - link, # type: Link - download_dir=None, # type: Optional[str] - hashes=None # type: Optional[Hashes] -): - # type: (...) -> File - """Get file and optionally check its hash. - """ - # If a download dir is specified, is the file already there and valid? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir( - link, download_dir, hashes - ) - - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link.file_path - - # If --require-hashes is off, `hashes` is either empty, the - # link's embedded hash, or MissingHashes; it is required to - # match. If --require-hashes is on, we are satisfied by any - # hash in `hashes` matching: a URL-based or an option-based - # one; no internet-sourced hash will be in `hashes`. - if hashes: - hashes.check_against_path(from_path) - - content_type = mimetypes.guess_type(from_path)[0] - - return File(from_path, content_type) - - -def unpack_url( - link, # type: Link - location, # type: str - downloader, # type: Downloader - download_dir=None, # type: Optional[str] - hashes=None, # type: Optional[Hashes] -): - # type: (...) -> Optional[File] - """Unpack link into location, downloading if required. - - :param hashes: A Hashes object, one of whose embedded hashes must match, - or HashMismatch will be raised. If the Hashes is empty, no matches are - required, and unhashable types of requirements (like VCS ones, which - would ordinarily raise HashUnsupported) are allowed. - """ - # non-editable vcs urls - if link.is_vcs: - unpack_vcs_link(link, location) - return None - - # If it's a url to a local directory - if link.is_existing_dir(): - if os.path.isdir(location): - rmtree(location) - _copy_source_tree(link.file_path, location) - return None - - # file urls - if link.is_file: - file = get_file_url(link, download_dir, hashes=hashes) - - # http urls - else: - file = get_http_url( - link, - downloader, - download_dir, - hashes=hashes, - ) - - # unpack the archive to the build dir location. even when only downloading - # archives, they have to be unpacked to parse dependencies - unpack_file(file.path, location, file.content_type) - - return file - - -def _download_http_url( - link, # type: Link - downloader, # type: Downloader - temp_dir, # type: str - hashes, # type: Optional[Hashes] -): - # type: (...) -> Tuple[str, str] - """Download link url into temp_dir using provided session""" - download = downloader(link) - - file_path = os.path.join(temp_dir, download.filename) - with open(file_path, 'wb') as content_file: - for chunk in download.chunks: - content_file.write(chunk) - - if hashes: - hashes.check_against_path(file_path) - - return file_path, download.response.headers.get('content-type', '') - - -def _check_download_dir(link, download_dir, hashes): - # type: (Link, str, Optional[Hashes]) -> Optional[str] - """ Check download_dir for previously downloaded file with correct hash - If a correct file is found return its path else None - """ - download_path = os.path.join(download_dir, link.filename) - - if not os.path.exists(download_path): - return None - - # If already downloaded, does its hash match? - logger.info('File was already downloaded %s', download_path) - if hashes: - try: - hashes.check_against_path(download_path) - except HashMismatch: - logger.warning( - 'Previously-downloaded file %s has bad hash. ' - 'Re-downloading.', - download_path - ) - os.unlink(download_path) - return None - return download_path - - -class RequirementPreparer(object): - """Prepares a Requirement - """ - - def __init__( - self, - build_dir, # type: str - download_dir, # type: Optional[str] - src_dir, # type: str - wheel_download_dir, # type: Optional[str] - build_isolation, # type: bool - req_tracker, # type: RequirementTracker - downloader, # type: Downloader - finder, # type: PackageFinder - require_hashes, # type: bool - use_user_site, # type: bool - ): - # type: (...) -> None - super(RequirementPreparer, self).__init__() - - self.src_dir = src_dir - self.build_dir = build_dir - self.req_tracker = req_tracker - self.downloader = downloader - self.finder = finder - - # Where still-packed archives should be written to. If None, they are - # not saved, and are deleted immediately after unpacking. - self.download_dir = download_dir - - # Where still-packed .whl files should be written to. If None, they are - # written to the download_dir parameter. Separate to download_dir to - # permit only keeping wheel archives for pip wheel. - self.wheel_download_dir = wheel_download_dir - - # NOTE - # download_dir and wheel_download_dir overlap semantically and may - # be combined if we're willing to have non-wheel archives present in - # the wheelhouse output by 'pip wheel'. - - # Is build isolation allowed? - self.build_isolation = build_isolation - - # Should hash-checking be required? - self.require_hashes = require_hashes - - # Should install in user site-packages? - self.use_user_site = use_user_site - - @property - def _download_should_save(self): - # type: () -> bool - if not self.download_dir: - return False - - if os.path.exists(self.download_dir): - return True - - logger.critical('Could not find download directory') - raise InstallationError( - "Could not find or access download directory '{}'" - .format(self.download_dir)) - - def prepare_linked_requirement( - self, - req, # type: InstallRequirement - ): - # type: (...) -> AbstractDistribution - """Prepare a requirement that would be obtained from req.link - """ - assert req.link - link = req.link - - # TODO: Breakup into smaller functions - if link.scheme == 'file': - path = link.file_path - logger.info('Processing %s', display_path(path)) - else: - logger.info('Collecting %s', req.req or req) - - download_dir = self.download_dir - if link.is_wheel and self.wheel_download_dir: - # when doing 'pip wheel` we download wheels to a - # dedicated dir. - download_dir = self.wheel_download_dir - - if link.is_wheel: - if download_dir: - # When downloading, we only unpack wheels to get - # metadata. - autodelete_unpacked = True - else: - # When installing a wheel, we use the unpacked - # wheel. - autodelete_unpacked = False - else: - # We always delete unpacked sdists after pip runs. - autodelete_unpacked = True - - with indent_log(): - # Since source_dir is only set for editable requirements. - assert req.source_dir is None - req.ensure_has_source_dir(self.build_dir, autodelete_unpacked) - # If a checkout exists, it's unwise to keep going. version - # inconsistencies are logged later, but do not fail the - # installation. - # FIXME: this won't upgrade when there's an existing - # package unpacked in `req.source_dir` - if os.path.exists(os.path.join(req.source_dir, 'setup.py')): - raise PreviousBuildDirError( - "pip can't proceed with requirements '{}' due to a" - " pre-existing build directory ({}). This is " - "likely due to a previous installation that failed" - ". pip is being responsible and not assuming it " - "can delete this. Please delete it and try again." - .format(req, req.source_dir) - ) - - # Now that we have the real link, we can tell what kind of - # requirements we have and raise some more informative errors - # than otherwise. (For example, we can raise VcsHashUnsupported - # for a VCS URL rather than HashMissing.) - if self.require_hashes: - # We could check these first 2 conditions inside - # unpack_url and save repetition of conditions, but then - # we would report less-useful error messages for - # unhashable requirements, complaining that there's no - # hash provided. - if link.is_vcs: - raise VcsHashUnsupported() - elif link.is_existing_dir(): - raise DirectoryUrlHashUnsupported() - if not req.original_link and not req.is_pinned: - # Unpinned packages are asking for trouble when a new - # version is uploaded. This isn't a security check, but - # it saves users a surprising hash mismatch in the - # future. - # - # file:/// URLs aren't pinnable, so don't complain - # about them not being pinned. - raise HashUnpinned() - - hashes = req.hashes(trust_internet=not self.require_hashes) - if self.require_hashes and not hashes: - # Known-good hashes are missing for this requirement, so - # shim it with a facade object that will provoke hash - # computation and then raise a HashMissing exception - # showing the user what the hash should be. - hashes = MissingHashes() - - try: - local_file = unpack_url( - link, req.source_dir, self.downloader, download_dir, - hashes=hashes, - ) - except requests.HTTPError as exc: - logger.critical( - 'Could not install requirement %s because of error %s', - req, - exc, - ) - raise InstallationError( - 'Could not install requirement {} because of HTTP ' - 'error {} for URL {}'.format(req, exc, link) - ) - - # For use in later processing, preserve the file path on the - # requirement. - if local_file: - req.local_file_path = local_file.path - - abstract_dist = _get_prepared_distribution( - req, self.req_tracker, self.finder, self.build_isolation, - ) - - if download_dir: - if link.is_existing_dir(): - logger.info('Link is a directory, ignoring download_dir') - elif local_file: - download_location = os.path.join( - download_dir, link.filename - ) - if not os.path.exists(download_location): - shutil.copy(local_file.path, download_location) - logger.info( - 'Saved %s', display_path(download_location) - ) - - if self._download_should_save: - # Make a .zip of the source_dir we already created. - if link.is_vcs: - req.archive(self.download_dir) - return abstract_dist - - def prepare_editable_requirement( - self, - req, # type: InstallRequirement - ): - # type: (...) -> AbstractDistribution - """Prepare an editable requirement - """ - assert req.editable, "cannot prepare a non-editable req as editable" - - logger.info('Obtaining %s', req) - - with indent_log(): - if self.require_hashes: - raise InstallationError( - 'The editable requirement {} cannot be installed when ' - 'requiring hashes, because there is no single file to ' - 'hash.'.format(req) - ) - req.ensure_has_source_dir(self.src_dir) - req.update_editable(not self._download_should_save) - - abstract_dist = _get_prepared_distribution( - req, self.req_tracker, self.finder, self.build_isolation, - ) - - if self._download_should_save: - req.archive(self.download_dir) - req.check_if_exists(self.use_user_site) - - return abstract_dist - - def prepare_installed_requirement( - self, - req, # type: InstallRequirement - skip_reason # type: str - ): - # type: (...) -> AbstractDistribution - """Prepare an already-installed requirement - """ - assert req.satisfied_by, "req should have been satisfied but isn't" - assert skip_reason is not None, ( - "did not get skip reason skipped but req.satisfied_by " - "is set to {}".format(req.satisfied_by) - ) - logger.info( - 'Requirement %s: %s (%s)', - skip_reason, req, req.satisfied_by.version - ) - with indent_log(): - if self.require_hashes: - logger.debug( - 'Since it is already installed, we are trusting this ' - 'package without checking its hash. To ensure a ' - 'completely repeatable environment, install into an ' - 'empty virtualenv.' - ) - abstract_dist = InstalledDistribution(req) - - return abstract_dist diff --git a/env/lib/python3.8/site-packages/pip/_internal/pyproject.py b/env/lib/python3.8/site-packages/pip/_internal/pyproject.py deleted file mode 100644 index 6b4faf7a..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/pyproject.py +++ /dev/null @@ -1,196 +0,0 @@ -from __future__ import absolute_import - -import io -import os -import sys -from collections import namedtuple - -from pip._vendor import six, toml -from pip._vendor.packaging.requirements import InvalidRequirement, Requirement - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional, List - - -def _is_list_of_str(obj): - # type: (Any) -> bool - return ( - isinstance(obj, list) and - all(isinstance(item, six.string_types) for item in obj) - ) - - -def make_pyproject_path(unpacked_source_directory): - # type: (str) -> str - path = os.path.join(unpacked_source_directory, 'pyproject.toml') - - # Python2 __file__ should not be unicode - if six.PY2 and isinstance(path, six.text_type): - path = path.encode(sys.getfilesystemencoding()) - - return path - - -BuildSystemDetails = namedtuple('BuildSystemDetails', [ - 'requires', 'backend', 'check', 'backend_path' -]) - - -def load_pyproject_toml( - use_pep517, # type: Optional[bool] - pyproject_toml, # type: str - setup_py, # type: str - req_name # type: str -): - # type: (...) -> Optional[BuildSystemDetails] - """Load the pyproject.toml file. - - Parameters: - use_pep517 - Has the user requested PEP 517 processing? None - means the user hasn't explicitly specified. - pyproject_toml - Location of the project's pyproject.toml file - setup_py - Location of the project's setup.py file - req_name - The name of the requirement we're processing (for - error reporting) - - Returns: - None if we should use the legacy code path, otherwise a tuple - ( - requirements from pyproject.toml, - name of PEP 517 backend, - requirements we should check are installed after setting - up the build environment - directory paths to import the backend from (backend-path), - relative to the project root. - ) - """ - has_pyproject = os.path.isfile(pyproject_toml) - has_setup = os.path.isfile(setup_py) - - if has_pyproject: - with io.open(pyproject_toml, encoding="utf-8") as f: - pp_toml = toml.load(f) - build_system = pp_toml.get("build-system") - else: - build_system = None - - # The following cases must use PEP 517 - # We check for use_pep517 being non-None and falsey because that means - # the user explicitly requested --no-use-pep517. The value 0 as - # opposed to False can occur when the value is provided via an - # environment variable or config file option (due to the quirk of - # strtobool() returning an integer in pip's configuration code). - if has_pyproject and not has_setup: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project does not have a setup.py" - ) - use_pep517 = True - elif build_system and "build-backend" in build_system: - if use_pep517 is not None and not use_pep517: - raise InstallationError( - "Disabling PEP 517 processing is invalid: " - "project specifies a build backend of {} " - "in pyproject.toml".format( - build_system["build-backend"] - ) - ) - use_pep517 = True - - # If we haven't worked out whether to use PEP 517 yet, - # and the user hasn't explicitly stated a preference, - # we do so if the project has a pyproject.toml file. - elif use_pep517 is None: - use_pep517 = has_pyproject - - # At this point, we know whether we're going to use PEP 517. - assert use_pep517 is not None - - # If we're using the legacy code path, there is nothing further - # for us to do here. - if not use_pep517: - return None - - if build_system is None: - # Either the user has a pyproject.toml with no build-system - # section, or the user has no pyproject.toml, but has opted in - # explicitly via --use-pep517. - # In the absence of any explicit backend specification, we - # assume the setuptools backend that most closely emulates the - # traditional direct setup.py execution, and require wheel and - # a version of setuptools that supports that backend. - - build_system = { - "requires": ["setuptools>=40.8.0", "wheel"], - "build-backend": "setuptools.build_meta:__legacy__", - } - - # If we're using PEP 517, we have build system information (either - # from pyproject.toml, or defaulted by the code above). - # Note that at this point, we do not know if the user has actually - # specified a backend, though. - assert build_system is not None - - # Ensure that the build-system section in pyproject.toml conforms - # to PEP 518. - error_template = ( - "{package} has a pyproject.toml file that does not comply " - "with PEP 518: {reason}" - ) - - # Specifying the build-system table but not the requires key is invalid - if "requires" not in build_system: - raise InstallationError( - error_template.format(package=req_name, reason=( - "it has a 'build-system' table but not " - "'build-system.requires' which is mandatory in the table" - )) - ) - - # Error out if requires is not a list of strings - requires = build_system["requires"] - if not _is_list_of_str(requires): - raise InstallationError(error_template.format( - package=req_name, - reason="'build-system.requires' is not a list of strings.", - )) - - # Each requirement must be valid as per PEP 508 - for requirement in requires: - try: - Requirement(requirement) - except InvalidRequirement: - raise InstallationError( - error_template.format( - package=req_name, - reason=( - "'build-system.requires' contains an invalid " - "requirement: {!r}".format(requirement) - ), - ) - ) - - backend = build_system.get("build-backend") - backend_path = build_system.get("backend-path", []) - check = [] # type: List[str] - if backend is None: - # If the user didn't specify a backend, we assume they want to use - # the setuptools backend. But we can't be sure they have included - # a version of setuptools which supplies the backend, or wheel - # (which is needed by the backend) in their requirements. So we - # make a note to check that those requirements are present once - # we have set up the environment. - # This is quite a lot of work to check for a very specific case. But - # the problem is, that case is potentially quite common - projects that - # adopted PEP 518 early for the ability to specify requirements to - # execute setup.py, but never considered needing to mention the build - # tools themselves. The original PEP 518 code had a similar check (but - # implemented in a different way). - backend = "setuptools.build_meta:__legacy__" - check = ["setuptools>=40.8.0", "wheel"] - - return BuildSystemDetails(requires, backend, check, backend_path) diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/req/__init__.py deleted file mode 100644 index d2d027ad..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/__init__.py +++ /dev/null @@ -1,92 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging - -from pip._internal.utils.logging import indent_log -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -from .req_file import parse_requirements -from .req_install import InstallRequirement -from .req_set import RequirementSet - -if MYPY_CHECK_RUNNING: - from typing import Any, List, Sequence - -__all__ = [ - "RequirementSet", "InstallRequirement", - "parse_requirements", "install_given_reqs", -] - -logger = logging.getLogger(__name__) - - -class InstallationResult(object): - def __init__(self, name): - # type: (str) -> None - self.name = name - - def __repr__(self): - # type: () -> str - return "InstallationResult(name={!r})".format(self.name) - - -def install_given_reqs( - to_install, # type: List[InstallRequirement] - install_options, # type: List[str] - global_options=(), # type: Sequence[str] - *args, # type: Any - **kwargs # type: Any -): - # type: (...) -> List[InstallationResult] - """ - Install everything in the given list. - - (to be called after having downloaded and unpacked the packages) - """ - - if to_install: - logger.info( - 'Installing collected packages: %s', - ', '.join([req.name for req in to_install]), - ) - - installed = [] - - with indent_log(): - for requirement in to_install: - if requirement.should_reinstall: - logger.info('Attempting uninstall: %s', requirement.name) - with indent_log(): - uninstalled_pathset = requirement.uninstall( - auto_confirm=True - ) - try: - requirement.install( - install_options, - global_options, - *args, - **kwargs - ) - except Exception: - should_rollback = ( - requirement.should_reinstall and - not requirement.install_succeeded - ) - # if install did not succeed, rollback previous uninstall - if should_rollback: - uninstalled_pathset.rollback() - raise - else: - should_commit = ( - requirement.should_reinstall and - requirement.install_succeeded - ) - if should_commit: - uninstalled_pathset.commit() - - installed.append(InstallationResult(requirement.name)) - - return installed diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 3f15c30bac8098377d809ebf7561393a80f49e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2194 zcmaJCO>Y}TbY^zFUT^%7IBlu=AzTEgmZ(z+^#CeStF|hI5+I>!yHd4Ud&c&r`{B&a zw#3*MT5$u!6(N+|+6yO6969kD=E|l03y22ZTYJ;AMT|9X-@JM6&HMI^TFoJ_ZhiB+ zmjL!B9u6)O4i{jjKLOx`(~v~er4(@%GMB;E2#v^e&75Y2rO0wEz)Rc;%aQHcIbIGc zk>ff!Zifp|)vZz@EI9=EN?42PZar$ajcCzb1RjSk@G7qjOm|7Jou*jcrS74tgx7iF zA>j>i_<`Xb;Z458YY(aW8fP1%z5Em`ByFl2em70RObIWDMu}8wKy!kai&%MKGJsR_ zliQ!&_AY&R<Y@D9FK`yg3n*8D=HeTjDpdbEFSs2yMmv&KNKQ7^Iq27ez&_F;@yfD#7fB6 z4_CmK6%USq^1RMyTieCqIKG`5#m2|yu{>aJr{L>h7K(+q0XsLm3J9k=WI{ISE(O!s z+W6$FnogrHAAEI6PTSy-)lX#PtK6qHm5ZPwcWefla6}WO7)j529Zvsm;*4*tT|yyz z$Mdw~c~Qc%5b>(#ZDoEqyOGQI*x?sn#Gp!iR@MLDA3DLD6G#W#?NeGeg`dolf-9DqU^hl{Dl(y zq2}aAfR!ql+7nwonv{2(UAXz0+$Qm{TQiQ|kYiezROBCUzkv6X(oR*?fL=n&DcL&v z{PhVIwmr_A7OZ)WTjHLO+iDoZgH{l?)KIkY{%M8KY#k?OJ*|>fSG0Q2sDiirK2&9E z=-)#Tp4^Ya#OFwld8;VrTn|>ZKM-j(_II2qozPA41KTn;=5<$xJE%+6Ijaq5mY0jsIgj4-l4!Jg4pm`sSkS!V zw}V$^M(2E(fT!syAcfHQ=tZSOG*W1L7SDyypM>}9pp{h~HC%L{<*9T$J^+T^Xo4y>R+PZr`|5oPg@XP{) zvY6I-dEZLGy^*hmsZhF6cvRR^n-gYcy_5%u!{$v)z()W`-J~XEw7F-NOa{G5Em{W% zw0{;2mfx{GX0T_>WPjUMomte{VS&8#T;=s{m&x1aKu~r!fbv>^Xc?54y;;of*H=!|RQwzg&AcXrV=UIlvws14L_|IS diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc deleted file mode 100644 index ad16b9e8bbb70a3d973819e93a99d4cc5e24d736..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10847 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 MJ8C6!$;`h02NQm{u>b%7 diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc deleted file mode 100644 index 02c9874267d742303e4a5403ddf741aad1d6aea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5840 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc deleted file mode 100644 index d452d0e6b642ae97d8d06d7861dd0b805ae9d3d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4055 zcmZ`+TW=f36`t7}mlsj8qWBgkVS=VD+geVY_#s9b#B~JMh@vF&B{rL4yW)(cmG(l- z4sDAei^4LB0!0xZzkteH{zf1ABj&YF{R@3bzcVY^mLe}PXKrWD&Ya744)4s(H5i_I zfBRST_eIA3Lz5RD50j74N&_O8;3>;^k8>J3snc_8@Ah2Vdp*zge$Tgk&sh1Muwy@MX02X}Gucv8@CE5y*6y|KUM-!^7J3WWsotqMdoj z_FlF7VR||{(>r6w_4I6Zu6GV{{ONi5+5zufkk0n&q9K}3**@>RVP`EdXJ>ETV4^MN zpE5BoJNs_$E#cf^-G%?+eyq#Qe7sQ>=}^lk$p(eeYglXci(JdcI!!h%V>)+RW`j=> zCHuNidstZf?EV+`qw9ZIx&CRierIj%=GqO*rsBTbi2FOY_Xe^X81Iv$uT6MUOBLfy z6MjC>Ns-5?ac@a&JYqBcog8Z<^k!b_I8E2(?hxO~WUjI5ttRwqvfa0Bk~ z1@54=@oP8^Z@3FQMigbF}sTeGCM7n8idR~bp$`)6QB{=3iThtXygzyDPLhi*S8wBtqt4Ad(Mg;pBPlu?!z2|Q z%bDbxomh9?DZ4GT07i8R#JDh~qKlgP%Hu@e($J}ygH5HHX;KkD8E+8lEvq9Fq{SvQ zYkVO$hMQ*bh48su*`(_lPZfnWZeKq(wZoHIb62E8BG2I45pFVzy_rR?V6$8TVQz~z zU>=W$KL#*V%V}`6jP)aCvWy@fqm}C*lJ&S?z)dckrwq913J<*}d=a4cMNNe015pf^;3@l`?&xeoZSB zIxpxlj1VA+j-ne_F9Q(f1W?`RwVzsNdB)r4#CQ16_}P7sr{L{VZg1d_zmCZl=>{w0 z8zEPuq(qzW+!UwwiX9_~?z341&+AiuuT`XDQN}C{ z9gc&2jwDF&R^O?WPjur6((@QtyzhLwWWU3SMWhYJ%@nWyDAqjv9kM-5gHxt7j zjV?ek0_mOdm>{V-@2Ku6^?RsMeGFo}Vjy!sDkPcO&Cjc}?MtQd!UQX8pRcUlHo=2J zWwAER)uPxL4lIxQEr~coBK$`Rd0(BTu^S6xfrT z?D=Tcs|ZVMEU~Er+q(zWYOtU;MFC~=D`ETIo2awbNR+Zez~`!<@qGxz()lO@O)*A3vt@} zcY?Ai!ACHh^z{sTeuIfd9B#wwQJS`?QX$Qergj_8@{>>K{wzPuuKPmaVDppe2I^f1 ztUQX2cgK6gquXBx4R+SMwQy zI@S%9J>LljGQKTEzI%2gx4{EGI(x#AEaO^t4w*QjLN+MuMMLLzk{R7sLNXx+=g6ikAfL<-2SBrPhP=C4}Z=6S)|34H1@HPMd diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc deleted file mode 100644 index 1cdcae61f5c8ae08d105dd2ee82101ac3975670a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17460 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/constructors.py b/env/lib/python3.8/site-packages/pip/_internal/req/constructors.py deleted file mode 100644 index c9f1fe71..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/constructors.py +++ /dev/null @@ -1,464 +0,0 @@ -"""Backing implementation for InstallRequirement's various constructors - -The idea here is that these formed a major chunk of InstallRequirement's size -so, moving them and support code dedicated to them outside of that class -helps creates for better understandability for the rest of the code. - -These are meant to be used elsewhere within pip to create instances of -InstallRequirement. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import logging -import os -import re - -from pip._vendor.packaging.markers import Marker -from pip._vendor.packaging.requirements import InvalidRequirement, Requirement -from pip._vendor.packaging.specifiers import Specifier -from pip._vendor.pkg_resources import RequirementParseError, parse_requirements - -from pip._internal.exceptions import InstallationError -from pip._internal.models.index import PyPI, TestPyPI -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.pyproject import make_pyproject_path -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.filetypes import ARCHIVE_EXTENSIONS -from pip._internal.utils.misc import is_installable_dir, splitext -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs import is_url, vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Dict, Optional, Set, Tuple, Union, - ) - from pip._internal.req.req_file import ParsedRequirement - - -__all__ = [ - "install_req_from_editable", "install_req_from_line", - "parse_editable" -] - -logger = logging.getLogger(__name__) -operators = Specifier._operators.keys() - - -def is_archive_file(name): - # type: (str) -> bool - """Return True if `name` is a considered as an archive file.""" - ext = splitext(name)[1].lower() - if ext in ARCHIVE_EXTENSIONS: - return True - return False - - -def _strip_extras(path): - # type: (str) -> Tuple[str, Optional[str]] - m = re.match(r'^(.+)(\[[^\]]+\])$', path) - extras = None - if m: - path_no_extras = m.group(1) - extras = m.group(2) - else: - path_no_extras = path - - return path_no_extras, extras - - -def convert_extras(extras): - # type: (Optional[str]) -> Set[str] - if not extras: - return set() - return Requirement("placeholder" + extras.lower()).extras - - -def parse_editable(editable_req): - # type: (str) -> Tuple[Optional[str], str, Optional[Set[str]]] - """Parses an editable requirement into: - - a requirement name - - an URL - - extras - - editable options - Accepted requirements: - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir - .[some_extra] - """ - - url = editable_req - - # If a file path is specified with extras, strip off the extras. - url_no_extras, extras = _strip_extras(url) - - if os.path.isdir(url_no_extras): - if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): - msg = ( - 'File "setup.py" not found. Directory cannot be installed ' - 'in editable mode: {}'.format(os.path.abspath(url_no_extras)) - ) - pyproject_path = make_pyproject_path(url_no_extras) - if os.path.isfile(pyproject_path): - msg += ( - '\n(A "pyproject.toml" file was found, but editable ' - 'mode currently requires a setup.py based build.)' - ) - raise InstallationError(msg) - - # Treating it as code that has already been checked out - url_no_extras = path_to_url(url_no_extras) - - if url_no_extras.lower().startswith('file:'): - package_name = Link(url_no_extras).egg_fragment - if extras: - return ( - package_name, - url_no_extras, - Requirement("placeholder" + extras.lower()).extras, - ) - else: - return package_name, url_no_extras, None - - for version_control in vcs: - if url.lower().startswith('{}:'.format(version_control)): - url = '{}+{}'.format(version_control, url) - break - - if '+' not in url: - raise InstallationError( - '{} is not a valid editable requirement. ' - 'It should either be a path to a local project or a VCS URL ' - '(beginning with svn+, git+, hg+, or bzr+).'.format(editable_req) - ) - - vc_type = url.split('+', 1)[0].lower() - - if not vcs.get_backend(vc_type): - backends = ", ".join([bends.name + '+URL' for bends in vcs.backends]) - error_message = "For --editable={}, " \ - "only {} are currently supported".format( - editable_req, backends) - raise InstallationError(error_message) - - package_name = Link(url).egg_fragment - if not package_name: - raise InstallationError( - "Could not detect requirement name for '{}', please specify one " - "with #egg=your_package_name".format(editable_req) - ) - return package_name, url, None - - -def deduce_helpful_msg(req): - # type: (str) -> str - """Returns helpful msg in case requirements file does not exist, - or cannot be parsed. - - :params req: Requirements file path - """ - msg = "" - if os.path.exists(req): - msg = " It does exist." - # Try to parse and check if it is a requirements file. - try: - with open(req, 'r') as fp: - # parse first line only - next(parse_requirements(fp.read())) - msg += ( - "The argument you provided " - "({}) appears to be a" - " requirements file. If that is the" - " case, use the '-r' flag to install" - " the packages specified within it." - ).format(req) - except RequirementParseError: - logger.debug("Cannot parse '{}' as requirements \ - file".format(req), exc_info=True) - else: - msg += " File '{}' does not exist.".format(req) - return msg - - -class RequirementParts(object): - def __init__( - self, - requirement, # type: Optional[Requirement] - link, # type: Optional[Link] - markers, # type: Optional[Marker] - extras, # type: Set[str] - ): - self.requirement = requirement - self.link = link - self.markers = markers - self.extras = extras - - -def parse_req_from_editable(editable_req): - # type: (str) -> RequirementParts - name, url, extras_override = parse_editable(editable_req) - - if name is not None: - try: - req = Requirement(name) - except InvalidRequirement: - raise InstallationError("Invalid requirement: '{}'".format(name)) - else: - req = None - - link = Link(url) - - return RequirementParts(req, link, None, extras_override) - - -# ---- The actual constructors follow ---- - - -def install_req_from_editable( - editable_req, # type: str - comes_from=None, # type: Optional[Union[InstallRequirement, str]] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - constraint=False # type: bool -): - # type: (...) -> InstallRequirement - - parts = parse_req_from_editable(editable_req) - - return InstallRequirement( - parts.requirement, - comes_from=comes_from, - editable=True, - link=parts.link, - constraint=constraint, - use_pep517=use_pep517, - isolated=isolated, - install_options=options.get("install_options", []) if options else [], - global_options=options.get("global_options", []) if options else [], - hash_options=options.get("hashes", {}) if options else {}, - extras=parts.extras, - ) - - -def _looks_like_path(name): - # type: (str) -> bool - """Checks whether the string "looks like" a path on the filesystem. - - This does not check whether the target actually exists, only judge from the - appearance. - - Returns true if any of the following conditions is true: - * a path separator is found (either os.path.sep or os.path.altsep); - * a dot is found (which represents the current directory). - """ - if os.path.sep in name: - return True - if os.path.altsep is not None and os.path.altsep in name: - return True - if name.startswith("."): - return True - return False - - -def _get_url_from_path(path, name): - # type: (str, str) -> str - """ - First, it checks whether a provided path is an installable directory - (e.g. it has a setup.py). If it is, returns the path. - - If false, check if the path is an archive file (such as a .whl). - The function checks if the path is a file. If false, if the path has - an @, it will treat it as a PEP 440 URL requirement and return the path. - """ - if _looks_like_path(name) and os.path.isdir(path): - if is_installable_dir(path): - return path_to_url(path) - raise InstallationError( - "Directory {name!r} is not installable. Neither 'setup.py' " - "nor 'pyproject.toml' found.".format(**locals()) - ) - if not is_archive_file(path): - return None - if os.path.isfile(path): - return path_to_url(path) - urlreq_parts = name.split('@', 1) - if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]): - # If the path contains '@' and the part before it does not look - # like a path, try to treat it as a PEP 440 URL req instead. - return None - logger.warning( - 'Requirement %r looks like a filename, but the ' - 'file does not exist', - name - ) - return path_to_url(path) - - -def parse_req_from_line(name, line_source): - # type: (str, Optional[str]) -> RequirementParts - if is_url(name): - marker_sep = '; ' - else: - marker_sep = ';' - if marker_sep in name: - name, markers_as_string = name.split(marker_sep, 1) - markers_as_string = markers_as_string.strip() - if not markers_as_string: - markers = None - else: - markers = Marker(markers_as_string) - else: - markers = None - name = name.strip() - req_as_string = None - path = os.path.normpath(os.path.abspath(name)) - link = None - extras_as_string = None - - if is_url(name): - link = Link(name) - else: - p, extras_as_string = _strip_extras(path) - url = _get_url_from_path(p, name) - if url is not None: - link = Link(url) - - # it's a local file, dir, or url - if link: - # Handle relative file URLs - if link.scheme == 'file' and re.search(r'\.\./', link.url): - link = Link( - path_to_url(os.path.normpath(os.path.abspath(link.path)))) - # wheel file - if link.is_wheel: - wheel = Wheel(link.filename) # can raise InvalidWheelFilename - req_as_string = "{wheel.name}=={wheel.version}".format(**locals()) - else: - # set the req to the egg fragment. when it's not there, this - # will become an 'unnamed' requirement - req_as_string = link.egg_fragment - - # a requirement specifier - else: - req_as_string = name - - extras = convert_extras(extras_as_string) - - def with_source(text): - # type: (str) -> str - if not line_source: - return text - return '{} (from {})'.format(text, line_source) - - if req_as_string is not None: - try: - req = Requirement(req_as_string) - except InvalidRequirement: - if os.path.sep in req_as_string: - add_msg = "It looks like a path." - add_msg += deduce_helpful_msg(req_as_string) - elif ('=' in req_as_string and - not any(op in req_as_string for op in operators)): - add_msg = "= is not a valid operator. Did you mean == ?" - else: - add_msg = '' - msg = with_source( - 'Invalid requirement: {!r}'.format(req_as_string) - ) - if add_msg: - msg += '\nHint: {}'.format(add_msg) - raise InstallationError(msg) - else: - req = None - - return RequirementParts(req, link, markers, extras) - - -def install_req_from_line( - name, # type: str - comes_from=None, # type: Optional[Union[str, InstallRequirement]] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - constraint=False, # type: bool - line_source=None, # type: Optional[str] -): - # type: (...) -> InstallRequirement - """Creates an InstallRequirement from a name, which might be a - requirement, directory containing 'setup.py', filename, or URL. - - :param line_source: An optional string describing where the line is from, - for logging purposes in case of an error. - """ - parts = parse_req_from_line(name, line_source) - - return InstallRequirement( - parts.requirement, comes_from, link=parts.link, markers=parts.markers, - use_pep517=use_pep517, isolated=isolated, - install_options=options.get("install_options", []) if options else [], - global_options=options.get("global_options", []) if options else [], - hash_options=options.get("hashes", {}) if options else {}, - constraint=constraint, - extras=parts.extras, - ) - - -def install_req_from_req_string( - req_string, # type: str - comes_from=None, # type: Optional[InstallRequirement] - isolated=False, # type: bool - use_pep517=None # type: Optional[bool] -): - # type: (...) -> InstallRequirement - try: - req = Requirement(req_string) - except InvalidRequirement: - raise InstallationError("Invalid requirement: '{}'".format(req_string)) - - domains_not_allowed = [ - PyPI.file_storage_domain, - TestPyPI.file_storage_domain, - ] - if (req.url and comes_from and comes_from.link and - comes_from.link.netloc in domains_not_allowed): - # Explicitly disallow pypi packages that depend on external urls - raise InstallationError( - "Packages installed from PyPI cannot depend on packages " - "which are not also hosted on PyPI.\n" - "{} depends on {} ".format(comes_from.name, req) - ) - - return InstallRequirement( - req, comes_from, isolated=isolated, use_pep517=use_pep517 - ) - - -def install_req_from_parsed_requirement( - parsed_req, # type: ParsedRequirement - isolated=False, # type: bool - use_pep517=None # type: Optional[bool] -): - # type: (...) -> InstallRequirement - if parsed_req.is_editable: - req = install_req_from_editable( - parsed_req.requirement, - comes_from=parsed_req.comes_from, - use_pep517=use_pep517, - constraint=parsed_req.constraint, - isolated=isolated, - ) - - else: - req = install_req_from_line( - parsed_req.requirement, - comes_from=parsed_req.comes_from, - use_pep517=use_pep517, - isolated=isolated, - options=parsed_req.options, - constraint=parsed_req.constraint, - line_source=parsed_req.line_source, - ) - return req diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/req_file.py b/env/lib/python3.8/site-packages/pip/_internal/req/req_file.py deleted file mode 100644 index 63cab76f..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/req_file.py +++ /dev/null @@ -1,582 +0,0 @@ -""" -Requirements file parsing -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import optparse -import os -import re -import shlex -import sys - -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.cli import cmdoptions -from pip._internal.exceptions import ( - InstallationError, - RequirementsFileParseError, -) -from pip._internal.models.search_scope import SearchScope -from pip._internal.utils.encoding import auto_decode -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import get_url_scheme - -if MYPY_CHECK_RUNNING: - from optparse import Values - from typing import ( - Any, Callable, Dict, Iterator, List, NoReturn, Optional, Text, Tuple, - ) - - from pip._internal.index.package_finder import PackageFinder - from pip._internal.network.session import PipSession - - ReqFileLines = Iterator[Tuple[int, Text]] - - LineParser = Callable[[Text], Tuple[str, Values]] - - -__all__ = ['parse_requirements'] - -SCHEME_RE = re.compile(r'^(http|https|file):', re.I) -COMMENT_RE = re.compile(r'(^|\s+)#.*$') - -# Matches environment variable-style values in '${MY_VARIABLE_1}' with the -# variable name consisting of only uppercase letters, digits or the '_' -# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, -# 2013 Edition. -ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') - -SUPPORTED_OPTIONS = [ - cmdoptions.index_url, - cmdoptions.extra_index_url, - cmdoptions.no_index, - cmdoptions.constraints, - cmdoptions.requirements, - cmdoptions.editable, - cmdoptions.find_links, - cmdoptions.no_binary, - cmdoptions.only_binary, - cmdoptions.require_hashes, - cmdoptions.pre, - cmdoptions.trusted_host, - cmdoptions.always_unzip, # Deprecated -] # type: List[Callable[..., optparse.Option]] - -# options to be passed to requirements -SUPPORTED_OPTIONS_REQ = [ - cmdoptions.install_options, - cmdoptions.global_options, - cmdoptions.hash, -] # type: List[Callable[..., optparse.Option]] - -# the 'dest' string values -SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] - - -class ParsedRequirement(object): - def __init__( - self, - requirement, # type:str - is_editable, # type: bool - comes_from, # type: str - constraint, # type: bool - options=None, # type: Optional[Dict[str, Any]] - line_source=None, # type: Optional[str] - ): - # type: (...) -> None - self.requirement = requirement - self.is_editable = is_editable - self.comes_from = comes_from - self.options = options - self.constraint = constraint - self.line_source = line_source - - -class ParsedLine(object): - def __init__( - self, - filename, # type: str - lineno, # type: int - comes_from, # type: str - args, # type: str - opts, # type: Values - constraint, # type: bool - ): - # type: (...) -> None - self.filename = filename - self.lineno = lineno - self.comes_from = comes_from - self.opts = opts - self.constraint = constraint - - if args: - self.is_requirement = True - self.is_editable = False - self.requirement = args - elif opts.editables: - self.is_requirement = True - self.is_editable = True - # We don't support multiple -e on one line - self.requirement = opts.editables[0] - else: - self.is_requirement = False - - -def parse_requirements( - filename, # type: str - session, # type: PipSession - finder=None, # type: Optional[PackageFinder] - comes_from=None, # type: Optional[str] - options=None, # type: Optional[optparse.Values] - constraint=False, # type: bool -): - # type: (...) -> Iterator[ParsedRequirement] - """Parse a requirements file and yield InstallRequirement instances. - - :param filename: Path or url of requirements file. - :param session: PipSession instance. - :param finder: Instance of pip.index.PackageFinder. - :param comes_from: Origin description of requirements. - :param options: cli options. - :param constraint: If true, parsing a constraint file rather than - requirements file. - """ - line_parser = get_line_parser(finder) - parser = RequirementsFileParser(session, line_parser, comes_from) - - for parsed_line in parser.parse(filename, constraint): - parsed_req = handle_line( - parsed_line, - options=options, - finder=finder, - session=session - ) - if parsed_req is not None: - yield parsed_req - - -def preprocess(content): - # type: (Text) -> ReqFileLines - """Split, filter, and join lines, and return a line iterator - - :param content: the content of the requirements file - """ - lines_enum = enumerate(content.splitlines(), start=1) # type: ReqFileLines - lines_enum = join_lines(lines_enum) - lines_enum = ignore_comments(lines_enum) - lines_enum = expand_env_variables(lines_enum) - return lines_enum - - -def handle_requirement_line( - line, # type: ParsedLine - options=None, # type: Optional[optparse.Values] -): - # type: (...) -> ParsedRequirement - - # preserve for the nested code path - line_comes_from = '{} {} (line {})'.format( - '-c' if line.constraint else '-r', line.filename, line.lineno, - ) - - assert line.is_requirement - - if line.is_editable: - # For editable requirements, we don't support per-requirement - # options, so just return the parsed requirement. - return ParsedRequirement( - requirement=line.requirement, - is_editable=line.is_editable, - comes_from=line_comes_from, - constraint=line.constraint, - ) - else: - if options: - # Disable wheels if the user has specified build options - cmdoptions.check_install_build_global(options, line.opts) - - # get the options that apply to requirements - req_options = {} - for dest in SUPPORTED_OPTIONS_REQ_DEST: - if dest in line.opts.__dict__ and line.opts.__dict__[dest]: - req_options[dest] = line.opts.__dict__[dest] - - line_source = 'line {} of {}'.format(line.lineno, line.filename) - return ParsedRequirement( - requirement=line.requirement, - is_editable=line.is_editable, - comes_from=line_comes_from, - constraint=line.constraint, - options=req_options, - line_source=line_source, - ) - - -def handle_option_line( - opts, # type: Values - filename, # type: str - lineno, # type: int - finder=None, # type: Optional[PackageFinder] - options=None, # type: Optional[optparse.Values] - session=None, # type: Optional[PipSession] -): - # type: (...) -> None - - # percolate hash-checking option upward - if opts.require_hashes: - options.require_hashes = opts.require_hashes - - # set finder options - elif finder: - find_links = finder.find_links - index_urls = finder.index_urls - if opts.index_url: - index_urls = [opts.index_url] - if opts.no_index is True: - index_urls = [] - if opts.extra_index_urls: - index_urls.extend(opts.extra_index_urls) - if opts.find_links: - # FIXME: it would be nice to keep track of the source - # of the find_links: support a find-links local path - # relative to a requirements file. - value = opts.find_links[0] - req_dir = os.path.dirname(os.path.abspath(filename)) - relative_to_reqs_file = os.path.join(req_dir, value) - if os.path.exists(relative_to_reqs_file): - value = relative_to_reqs_file - find_links.append(value) - - search_scope = SearchScope( - find_links=find_links, - index_urls=index_urls, - ) - finder.search_scope = search_scope - - if opts.pre: - finder.set_allow_all_prereleases() - - if session: - for host in opts.trusted_hosts or []: - source = 'line {} of {}'.format(lineno, filename) - session.add_trusted_host(host, source=source) - - -def handle_line( - line, # type: ParsedLine - options=None, # type: Optional[optparse.Values] - finder=None, # type: Optional[PackageFinder] - session=None, # type: Optional[PipSession] -): - # type: (...) -> Optional[ParsedRequirement] - """Handle a single parsed requirements line; This can result in - creating/yielding requirements, or updating the finder. - - :param line: The parsed line to be processed. - :param options: CLI options. - :param finder: The finder - updated by non-requirement lines. - :param session: The session - updated by non-requirement lines. - - Returns a ParsedRequirement object if the line is a requirement line, - otherwise returns None. - - For lines that contain requirements, the only options that have an effect - are from SUPPORTED_OPTIONS_REQ, and they are scoped to the - requirement. Other options from SUPPORTED_OPTIONS may be present, but are - ignored. - - For lines that do not contain requirements, the only options that have an - effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may - be present, but are ignored. These lines may contain multiple options - (although our docs imply only one is supported), and all our parsed and - affect the finder. - """ - - if line.is_requirement: - parsed_req = handle_requirement_line(line, options) - return parsed_req - else: - handle_option_line( - line.opts, - line.filename, - line.lineno, - finder, - options, - session, - ) - return None - - -class RequirementsFileParser(object): - def __init__( - self, - session, # type: PipSession - line_parser, # type: LineParser - comes_from, # type: str - ): - # type: (...) -> None - self._session = session - self._line_parser = line_parser - self._comes_from = comes_from - - def parse(self, filename, constraint): - # type: (str, bool) -> Iterator[ParsedLine] - """Parse a given file, yielding parsed lines. - """ - for line in self._parse_and_recurse(filename, constraint): - yield line - - def _parse_and_recurse(self, filename, constraint): - # type: (str, bool) -> Iterator[ParsedLine] - for line in self._parse_file(filename, constraint): - if ( - not line.is_requirement and - (line.opts.requirements or line.opts.constraints) - ): - # parse a nested requirements file - if line.opts.requirements: - req_path = line.opts.requirements[0] - nested_constraint = False - else: - req_path = line.opts.constraints[0] - nested_constraint = True - - # original file is over http - if SCHEME_RE.search(filename): - # do a url join so relative paths work - req_path = urllib_parse.urljoin(filename, req_path) - # original file and nested file are paths - elif not SCHEME_RE.search(req_path): - # do a join so relative paths work - req_path = os.path.join( - os.path.dirname(filename), req_path, - ) - - for inner_line in self._parse_and_recurse( - req_path, nested_constraint, - ): - yield inner_line - else: - yield line - - def _parse_file(self, filename, constraint): - # type: (str, bool) -> Iterator[ParsedLine] - _, content = get_file_content( - filename, self._session, comes_from=self._comes_from - ) - - lines_enum = preprocess(content) - - for line_number, line in lines_enum: - try: - args_str, opts = self._line_parser(line) - except OptionParsingError as e: - # add offending line - msg = 'Invalid requirement: {}\n{}'.format(line, e.msg) - raise RequirementsFileParseError(msg) - - yield ParsedLine( - filename, - line_number, - self._comes_from, - args_str, - opts, - constraint, - ) - - -def get_line_parser(finder): - # type: (Optional[PackageFinder]) -> LineParser - def parse_line(line): - # type: (Text) -> Tuple[str, Values] - # Build new parser for each line since it accumulates appendable - # options. - parser = build_parser() - defaults = parser.get_default_values() - defaults.index_url = None - if finder: - defaults.format_control = finder.format_control - - args_str, options_str = break_args_options(line) - # Prior to 2.7.3, shlex cannot deal with unicode entries - if sys.version_info < (2, 7, 3): - # https://github.com/python/mypy/issues/1174 - options_str = options_str.encode('utf8') # type: ignore - - # https://github.com/python/mypy/issues/1174 - opts, _ = parser.parse_args( - shlex.split(options_str), defaults) # type: ignore - - return args_str, opts - - return parse_line - - -def break_args_options(line): - # type: (Text) -> Tuple[str, Text] - """Break up the line into an args and options string. We only want to shlex - (and then optparse) the options, not the args. args can contain markers - which are corrupted by shlex. - """ - tokens = line.split(' ') - args = [] - options = tokens[:] - for token in tokens: - if token.startswith('-') or token.startswith('--'): - break - else: - args.append(token) - options.pop(0) - return ' '.join(args), ' '.join(options) # type: ignore - - -class OptionParsingError(Exception): - def __init__(self, msg): - # type: (str) -> None - self.msg = msg - - -def build_parser(): - # type: () -> optparse.OptionParser - """ - Return a parser for parsing requirement lines - """ - parser = optparse.OptionParser(add_help_option=False) - - option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ - for option_factory in option_factories: - option = option_factory() - parser.add_option(option) - - # By default optparse sys.exits on parsing errors. We want to wrap - # that in our own exception. - def parser_exit(self, msg): - # type: (Any, str) -> NoReturn - raise OptionParsingError(msg) - # NOTE: mypy disallows assigning to a method - # https://github.com/python/mypy/issues/2427 - parser.exit = parser_exit # type: ignore - - return parser - - -def join_lines(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """Joins a line ending in '\' with the previous line (except when following - comments). The joined line takes on the index of the first line. - """ - primary_line_number = None - new_line = [] # type: List[Text] - for line_number, line in lines_enum: - if not line.endswith('\\') or COMMENT_RE.match(line): - if COMMENT_RE.match(line): - # this ensures comments are always matched later - line = ' ' + line - if new_line: - new_line.append(line) - yield primary_line_number, ''.join(new_line) - new_line = [] - else: - yield line_number, line - else: - if not new_line: - primary_line_number = line_number - new_line.append(line.strip('\\')) - - # last line contains \ - if new_line: - yield primary_line_number, ''.join(new_line) - - # TODO: handle space after '\'. - - -def ignore_comments(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """ - Strips comments and filter empty lines. - """ - for line_number, line in lines_enum: - line = COMMENT_RE.sub('', line) - line = line.strip() - if line: - yield line_number, line - - -def expand_env_variables(lines_enum): - # type: (ReqFileLines) -> ReqFileLines - """Replace all environment variables that can be retrieved via `os.getenv`. - - The only allowed format for environment variables defined in the - requirement file is `${MY_VARIABLE_1}` to ensure two things: - - 1. Strings that contain a `$` aren't accidentally (partially) expanded. - 2. Ensure consistency across platforms for requirement files. - - These points are the result of a discussion on the `github pull - request #3514 `_. - - Valid characters in variable names follow the `POSIX standard - `_ and are limited - to uppercase letter, digits and the `_` (underscore). - """ - for line_number, line in lines_enum: - for env_var, var_name in ENV_VAR_RE.findall(line): - value = os.getenv(var_name) - if not value: - continue - - line = line.replace(env_var, value) - - yield line_number, line - - -def get_file_content(url, session, comes_from=None): - # type: (str, PipSession, Optional[str]) -> Tuple[str, Text] - """Gets the content of a file; it may be a filename, file: URL, or - http: URL. Returns (location, content). Content is unicode. - Respects # -*- coding: declarations on the retrieved files. - - :param url: File path or url. - :param session: PipSession instance. - :param comes_from: Origin description of requirements. - """ - scheme = get_url_scheme(url) - - if scheme in ['http', 'https']: - # FIXME: catch some errors - resp = session.get(url) - resp.raise_for_status() - return resp.url, resp.text - - elif scheme == 'file': - if comes_from and comes_from.startswith('http'): - raise InstallationError( - 'Requirements file {} references URL {}, ' - 'which is local'.format(comes_from, url) - ) - - path = url.split(':', 1)[1] - path = path.replace('\\', '/') - match = _url_slash_drive_re.match(path) - if match: - path = match.group(1) + ':' + path.split('|', 1)[1] - path = urllib_parse.unquote(path) - if path.startswith('/'): - path = '/' + path.lstrip('/') - url = path - - try: - with open(url, 'rb') as f: - content = auto_decode(f.read()) - except IOError as exc: - raise InstallationError( - 'Could not open requirements file: {}'.format(exc) - ) - return url, content - - -_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/req_install.py b/env/lib/python3.8/site-packages/pip/_internal/req/req_install.py deleted file mode 100644 index 3b28209b..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/req_install.py +++ /dev/null @@ -1,850 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging -import os -import shutil -import sys -import zipfile - -from pip._vendor import pkg_resources, six -from pip._vendor.packaging.requirements import Requirement -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import Version -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.pep517.wrappers import Pep517HookCaller - -from pip._internal.build_env import NoOpBuildEnvironment -from pip._internal.exceptions import InstallationError -from pip._internal.locations import get_scheme -from pip._internal.models.link import Link -from pip._internal.operations.build.metadata import generate_metadata -from pip._internal.operations.build.metadata_legacy import \ - generate_metadata as generate_metadata_legacy -from pip._internal.operations.install.editable_legacy import \ - install_editable as install_editable_legacy -from pip._internal.operations.install.legacy import LegacyInstallFailure -from pip._internal.operations.install.legacy import install as install_legacy -from pip._internal.operations.install.wheel import install_wheel -from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path -from pip._internal.req.req_uninstall import UninstallPathSet -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.direct_url_helpers import direct_url_from_link -from pip._internal.utils.hashes import Hashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - ask_path_exists, - backup_dir, - display_path, - dist_in_site_packages, - dist_in_usersite, - get_installed_version, - hide_url, - redact_auth_from_url, -) -from pip._internal.utils.packaging import get_metadata -from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.virtualenv import running_under_virtualenv -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Dict, Iterable, List, Optional, Sequence, Union, - ) - from pip._internal.build_env import BuildEnvironment - from pip._vendor.pkg_resources import Distribution - from pip._vendor.packaging.specifiers import SpecifierSet - from pip._vendor.packaging.markers import Marker - - -logger = logging.getLogger(__name__) - - -def _get_dist(metadata_directory): - # type: (str) -> Distribution - """Return a pkg_resources.Distribution for the provided - metadata directory. - """ - dist_dir = metadata_directory.rstrip(os.sep) - - # Build a PathMetadata object, from path to metadata. :wink: - base_dir, dist_dir_name = os.path.split(dist_dir) - metadata = pkg_resources.PathMetadata(base_dir, dist_dir) - - # Determine the correct Distribution object type. - if dist_dir.endswith(".egg-info"): - dist_cls = pkg_resources.Distribution - dist_name = os.path.splitext(dist_dir_name)[0] - else: - assert dist_dir.endswith(".dist-info") - dist_cls = pkg_resources.DistInfoDistribution - dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0] - - return dist_cls( - base_dir, - project_name=dist_name, - metadata=metadata, - ) - - -class InstallRequirement(object): - """ - Represents something that may be installed later on, may have information - about where to fetch the relevant requirement and also contains logic for - installing the said requirement. - """ - - def __init__( - self, - req, # type: Optional[Requirement] - comes_from, # type: Optional[Union[str, InstallRequirement]] - editable=False, # type: bool - link=None, # type: Optional[Link] - markers=None, # type: Optional[Marker] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - install_options=None, # type: Optional[List[str]] - global_options=None, # type: Optional[List[str]] - hash_options=None, # type: Optional[Dict[str, List[str]]] - constraint=False, # type: bool - extras=() # type: Iterable[str] - ): - # type: (...) -> None - assert req is None or isinstance(req, Requirement), req - self.req = req - self.comes_from = comes_from - self.constraint = constraint - self.editable = editable - - # source_dir is the local directory where the linked requirement is - # located, or unpacked. In case unpacking is needed, creating and - # populating source_dir is done by the RequirementPreparer. Note this - # is not necessarily the directory where pyproject.toml or setup.py is - # located - that one is obtained via unpacked_source_directory. - self.source_dir = None # type: Optional[str] - if self.editable: - assert link - if link.is_file: - self.source_dir = os.path.normpath( - os.path.abspath(link.file_path) - ) - - if link is None and req and req.url: - # PEP 508 URL requirement - link = Link(req.url) - self.link = self.original_link = link - self.original_link_is_in_wheel_cache = False - - # Path to any downloaded or already-existing package. - self.local_file_path = None # type: Optional[str] - if self.link and self.link.is_file: - self.local_file_path = self.link.file_path - - if extras: - self.extras = extras - elif req: - self.extras = { - pkg_resources.safe_extra(extra) for extra in req.extras - } - else: - self.extras = set() - if markers is None and req: - markers = req.marker - self.markers = markers - - # This holds the pkg_resources.Distribution object if this requirement - # is already available: - self.satisfied_by = None # type: Optional[Distribution] - # Whether the installation process should try to uninstall an existing - # distribution before installing this requirement. - self.should_reinstall = False - # Temporary build location - self._temp_build_dir = None # type: Optional[TempDirectory] - # Set to True after successful installation - self.install_succeeded = None # type: Optional[bool] - # Supplied options - self.install_options = install_options if install_options else [] - self.global_options = global_options if global_options else [] - self.hash_options = hash_options if hash_options else {} - # Set to True after successful preparation of this requirement - self.prepared = False - self.is_direct = False - - # Set by the legacy resolver when the requirement has been downloaded - # TODO: This introduces a strong coupling between the resolver and the - # requirement (the coupling was previously between the resolver - # and the requirement set). This should be refactored to allow - # the requirement to decide for itself when it has been - # successfully downloaded - but that is more tricky to get right, - # se we are making the change in stages. - self.successfully_downloaded = False - - self.isolated = isolated - self.build_env = NoOpBuildEnvironment() # type: BuildEnvironment - - # For PEP 517, the directory where we request the project metadata - # gets stored. We need this to pass to build_wheel, so the backend - # can ensure that the wheel matches the metadata (see the PEP for - # details). - self.metadata_directory = None # type: Optional[str] - - # The static build requirements (from pyproject.toml) - self.pyproject_requires = None # type: Optional[List[str]] - - # Build requirements that we will check are available - self.requirements_to_check = [] # type: List[str] - - # The PEP 517 backend we should use to build the project - self.pep517_backend = None # type: Optional[Pep517HookCaller] - - # Are we using PEP 517 for this requirement? - # After pyproject.toml has been loaded, the only valid values are True - # and False. Before loading, None is valid (meaning "use the default"). - # Setting an explicit value before loading pyproject.toml is supported, - # but after loading this flag should be treated as read only. - self.use_pep517 = use_pep517 - - def __str__(self): - # type: () -> str - if self.req: - s = str(self.req) - if self.link: - s += ' from {}'.format(redact_auth_from_url(self.link.url)) - elif self.link: - s = redact_auth_from_url(self.link.url) - else: - s = '' - if self.satisfied_by is not None: - s += ' in {}'.format(display_path(self.satisfied_by.location)) - if self.comes_from: - if isinstance(self.comes_from, six.string_types): - comes_from = self.comes_from # type: Optional[str] - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += ' (from {})'.format(comes_from) - return s - - def __repr__(self): - # type: () -> str - return '<{} object: {} editable={!r}>'.format( - self.__class__.__name__, str(self), self.editable) - - def format_debug(self): - # type: () -> str - """An un-tested helper for getting state, for debugging. - """ - attributes = vars(self) - names = sorted(attributes) - - state = ( - "{}={!r}".format(attr, attributes[attr]) for attr in sorted(names) - ) - return '<{name} object: {{{state}}}>'.format( - name=self.__class__.__name__, - state=", ".join(state), - ) - - # Things that are valid for all kinds of requirements? - @property - def name(self): - # type: () -> Optional[str] - if self.req is None: - return None - return six.ensure_str(pkg_resources.safe_name(self.req.name)) - - @property - def specifier(self): - # type: () -> SpecifierSet - return self.req.specifier - - @property - def is_pinned(self): - # type: () -> bool - """Return whether I am pinned to an exact version. - - For example, some-package==1.2 is pinned; some-package>1.2 is not. - """ - specifiers = self.specifier - return (len(specifiers) == 1 and - next(iter(specifiers)).operator in {'==', '==='}) - - @property - def installed_version(self): - # type: () -> Optional[str] - return get_installed_version(self.name) - - def match_markers(self, extras_requested=None): - # type: (Optional[Iterable[str]]) -> bool - if not extras_requested: - # Provide an extra to safely evaluate the markers - # without matching any extra - extras_requested = ('',) - if self.markers is not None: - return any( - self.markers.evaluate({'extra': extra}) - for extra in extras_requested) - else: - return True - - @property - def has_hash_options(self): - # type: () -> bool - """Return whether any known-good hashes are specified as options. - - These activate --require-hashes mode; hashes specified as part of a - URL do not. - - """ - return bool(self.hash_options) - - def hashes(self, trust_internet=True): - # type: (bool) -> Hashes - """Return a hash-comparer that considers my option- and URL-based - hashes to be known-good. - - Hashes in URLs--ones embedded in the requirements file, not ones - downloaded from an index server--are almost peers with ones from - flags. They satisfy --require-hashes (whether it was implicitly or - explicitly activated) but do not activate it. md5 and sha224 are not - allowed in flags, which should nudge people toward good algos. We - always OR all hashes together, even ones from URLs. - - :param trust_internet: Whether to trust URL-based (#md5=...) hashes - downloaded from the internet, as by populate_link() - - """ - good_hashes = self.hash_options.copy() - link = self.link if trust_internet else self.original_link - if link and link.hash: - good_hashes.setdefault(link.hash_name, []).append(link.hash) - return Hashes(good_hashes) - - def from_path(self): - # type: () -> Optional[str] - """Format a nice indicator to show where this "comes from" - """ - if self.req is None: - return None - s = str(self.req) - if self.comes_from: - if isinstance(self.comes_from, six.string_types): - comes_from = self.comes_from - else: - comes_from = self.comes_from.from_path() - if comes_from: - s += '->' + comes_from - return s - - def ensure_build_location(self, build_dir, autodelete): - # type: (str, bool) -> str - assert build_dir is not None - if self._temp_build_dir is not None: - assert self._temp_build_dir.path - return self._temp_build_dir.path - if self.req is None: - # Some systems have /tmp as a symlink which confuses custom - # builds (such as numpy). Thus, we ensure that the real path - # is returned. - self._temp_build_dir = TempDirectory( - kind=tempdir_kinds.REQ_BUILD, globally_managed=True - ) - - return self._temp_build_dir.path - if self.editable: - name = self.name.lower() - else: - name = self.name - # FIXME: Is there a better place to create the build_dir? (hg and bzr - # need this) - if not os.path.exists(build_dir): - logger.debug('Creating directory %s', build_dir) - os.makedirs(build_dir) - actual_build_dir = os.path.join(build_dir, name) - # `None` indicates that we respect the globally-configured deletion - # settings, which is what we actually want when auto-deleting. - delete_arg = None if autodelete else False - return TempDirectory( - path=actual_build_dir, - delete=delete_arg, - kind=tempdir_kinds.REQ_BUILD, - globally_managed=True, - ).path - - def _set_requirement(self): - # type: () -> None - """Set requirement after generating metadata. - """ - assert self.req is None - assert self.metadata is not None - assert self.source_dir is not None - - # Construct a Requirement object from the generated metadata - if isinstance(parse_version(self.metadata["Version"]), Version): - op = "==" - else: - op = "===" - - self.req = Requirement( - "".join([ - self.metadata["Name"], - op, - self.metadata["Version"], - ]) - ) - - def warn_on_mismatching_name(self): - # type: () -> None - metadata_name = canonicalize_name(self.metadata["Name"]) - if canonicalize_name(self.req.name) == metadata_name: - # Everything is fine. - return - - # If we're here, there's a mismatch. Log a warning about it. - logger.warning( - 'Generating metadata for package %s ' - 'produced metadata for project name %s. Fix your ' - '#egg=%s fragments.', - self.name, metadata_name, self.name - ) - self.req = Requirement(metadata_name) - - def check_if_exists(self, use_user_site): - # type: (bool) -> None - """Find an installed distribution that satisfies or conflicts - with this requirement, and set self.satisfied_by or - self.should_reinstall appropriately. - """ - if self.req is None: - return - # get_distribution() will resolve the entire list of requirements - # anyway, and we've already determined that we need the requirement - # in question, so strip the marker so that we don't try to - # evaluate it. - no_marker = Requirement(str(self.req)) - no_marker.marker = None - try: - self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) - except pkg_resources.DistributionNotFound: - return - except pkg_resources.VersionConflict: - existing_dist = pkg_resources.get_distribution( - self.req.name - ) - if use_user_site: - if dist_in_usersite(existing_dist): - self.should_reinstall = True - elif (running_under_virtualenv() and - dist_in_site_packages(existing_dist)): - raise InstallationError( - "Will not install to the user site because it will " - "lack sys.path precedence to {} in {}".format( - existing_dist.project_name, existing_dist.location) - ) - else: - self.should_reinstall = True - else: - if self.editable and self.satisfied_by: - self.should_reinstall = True - # when installing editables, nothing pre-existing should ever - # satisfy - self.satisfied_by = None - - # Things valid for wheels - @property - def is_wheel(self): - # type: () -> bool - if not self.link: - return False - return self.link.is_wheel - - # Things valid for sdists - @property - def unpacked_source_directory(self): - # type: () -> str - return os.path.join( - self.source_dir, - self.link and self.link.subdirectory_fragment or '') - - @property - def setup_py_path(self): - # type: () -> str - assert self.source_dir, "No source dir for {}".format(self) - setup_py = os.path.join(self.unpacked_source_directory, 'setup.py') - - # Python2 __file__ should not be unicode - if six.PY2 and isinstance(setup_py, six.text_type): - setup_py = setup_py.encode(sys.getfilesystemencoding()) - - return setup_py - - @property - def pyproject_toml_path(self): - # type: () -> str - assert self.source_dir, "No source dir for {}".format(self) - return make_pyproject_path(self.unpacked_source_directory) - - def load_pyproject_toml(self): - # type: () -> None - """Load the pyproject.toml file. - - After calling this routine, all of the attributes related to PEP 517 - processing for this requirement have been set. In particular, the - use_pep517 attribute can be used to determine whether we should - follow the PEP 517 or legacy (setup.py) code path. - """ - pyproject_toml_data = load_pyproject_toml( - self.use_pep517, - self.pyproject_toml_path, - self.setup_py_path, - str(self) - ) - - if pyproject_toml_data is None: - self.use_pep517 = False - return - - self.use_pep517 = True - requires, backend, check, backend_path = pyproject_toml_data - self.requirements_to_check = check - self.pyproject_requires = requires - self.pep517_backend = Pep517HookCaller( - self.unpacked_source_directory, backend, backend_path=backend_path, - ) - - def _generate_metadata(self): - # type: () -> str - """Invokes metadata generator functions, with the required arguments. - """ - if not self.use_pep517: - assert self.unpacked_source_directory - - return generate_metadata_legacy( - build_env=self.build_env, - setup_py_path=self.setup_py_path, - source_dir=self.unpacked_source_directory, - isolated=self.isolated, - details=self.name or "from {}".format(self.link) - ) - - assert self.pep517_backend is not None - - return generate_metadata( - build_env=self.build_env, - backend=self.pep517_backend, - ) - - def prepare_metadata(self): - # type: () -> None - """Ensure that project metadata is available. - - Under PEP 517, call the backend hook to prepare the metadata. - Under legacy processing, call setup.py egg-info. - """ - assert self.source_dir - - with indent_log(): - self.metadata_directory = self._generate_metadata() - - # Act on the newly generated metadata, based on the name and version. - if not self.name: - self._set_requirement() - else: - self.warn_on_mismatching_name() - - self.assert_source_matches_version() - - @property - def metadata(self): - # type: () -> Any - if not hasattr(self, '_metadata'): - self._metadata = get_metadata(self.get_dist()) - - return self._metadata - - def get_dist(self): - # type: () -> Distribution - return _get_dist(self.metadata_directory) - - def assert_source_matches_version(self): - # type: () -> None - assert self.source_dir - version = self.metadata['version'] - if self.req.specifier and version not in self.req.specifier: - logger.warning( - 'Requested %s, but installing version %s', - self, - version, - ) - else: - logger.debug( - 'Source in %s has version %s, which satisfies requirement %s', - display_path(self.source_dir), - version, - self, - ) - - # For both source distributions and editables - def ensure_has_source_dir(self, parent_dir, autodelete=False): - # type: (str, bool) -> None - """Ensure that a source_dir is set. - - This will create a temporary build dir if the name of the requirement - isn't known yet. - - :param parent_dir: The ideal pip parent_dir for the source_dir. - Generally src_dir for editables and build_dir for sdists. - :return: self.source_dir - """ - if self.source_dir is None: - self.source_dir = self.ensure_build_location( - parent_dir, autodelete - ) - - # For editable installations - def update_editable(self, obtain=True): - # type: (bool) -> None - if not self.link: - logger.debug( - "Cannot update repository at %s; repository location is " - "unknown", - self.source_dir, - ) - return - assert self.editable - assert self.source_dir - if self.link.scheme == 'file': - # Static paths don't get updated - return - assert '+' in self.link.url, \ - "bad url: {self.link.url!r}".format(**locals()) - vc_type, url = self.link.url.split('+', 1) - vcs_backend = vcs.get_backend(vc_type) - if vcs_backend: - if not self.link.is_vcs: - reason = ( - "This form of VCS requirement is being deprecated: {}." - ).format( - self.link.url - ) - replacement = None - if self.link.url.startswith("git+git@"): - replacement = ( - "git+https://git@example.com/..., " - "git+ssh://git@example.com/..., " - "or the insecure git+git://git@example.com/..." - ) - deprecated(reason, replacement, gone_in="21.0", issue=7554) - hidden_url = hide_url(self.link.url) - if obtain: - vcs_backend.obtain(self.source_dir, url=hidden_url) - else: - vcs_backend.export(self.source_dir, url=hidden_url) - else: - assert 0, ( - 'Unexpected version control type (in {}): {}'.format( - self.link, vc_type)) - - # Top-level Actions - def uninstall(self, auto_confirm=False, verbose=False): - # type: (bool, bool) -> Optional[UninstallPathSet] - """ - Uninstall the distribution currently satisfying this requirement. - - Prompts before removing or modifying files unless - ``auto_confirm`` is True. - - Refuses to delete or modify files outside of ``sys.prefix`` - - thus uninstallation within a virtual environment can only - modify that virtual environment, even if the virtualenv is - linked to global site-packages. - - """ - assert self.req - try: - dist = pkg_resources.get_distribution(self.req.name) - except pkg_resources.DistributionNotFound: - logger.warning("Skipping %s as it is not installed.", self.name) - return None - else: - logger.info('Found existing installation: %s', dist) - - uninstalled_pathset = UninstallPathSet.from_dist(dist) - uninstalled_pathset.remove(auto_confirm, verbose) - return uninstalled_pathset - - def _get_archive_name(self, path, parentdir, rootdir): - # type: (str, str, str) -> str - - def _clean_zip_name(name, prefix): - # type: (str, str) -> str - assert name.startswith(prefix + os.path.sep), ( - "name {name!r} doesn't start with prefix {prefix!r}" - .format(**locals()) - ) - name = name[len(prefix) + 1:] - name = name.replace(os.path.sep, '/') - return name - - path = os.path.join(parentdir, path) - name = _clean_zip_name(path, rootdir) - return self.name + '/' + name - - def archive(self, build_dir): - # type: (str) -> None - """Saves archive to provided build_dir. - - Used for saving downloaded VCS requirements as part of `pip download`. - """ - assert self.source_dir - - create_archive = True - archive_name = '{}-{}.zip'.format(self.name, self.metadata["version"]) - archive_path = os.path.join(build_dir, archive_name) - - if os.path.exists(archive_path): - response = ask_path_exists( - 'The file {} exists. (i)gnore, (w)ipe, ' - '(b)ackup, (a)bort '.format( - display_path(archive_path)), - ('i', 'w', 'b', 'a')) - if response == 'i': - create_archive = False - elif response == 'w': - logger.warning('Deleting %s', display_path(archive_path)) - os.remove(archive_path) - elif response == 'b': - dest_file = backup_dir(archive_path) - logger.warning( - 'Backing up %s to %s', - display_path(archive_path), - display_path(dest_file), - ) - shutil.move(archive_path, dest_file) - elif response == 'a': - sys.exit(-1) - - if not create_archive: - return - - zip_output = zipfile.ZipFile( - archive_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True, - ) - with zip_output: - dir = os.path.normcase( - os.path.abspath(self.unpacked_source_directory) - ) - for dirpath, dirnames, filenames in os.walk(dir): - for dirname in dirnames: - dir_arcname = self._get_archive_name( - dirname, parentdir=dirpath, rootdir=dir, - ) - zipdir = zipfile.ZipInfo(dir_arcname + '/') - zipdir.external_attr = 0x1ED << 16 # 0o755 - zip_output.writestr(zipdir, '') - for filename in filenames: - file_arcname = self._get_archive_name( - filename, parentdir=dirpath, rootdir=dir, - ) - filename = os.path.join(dirpath, filename) - zip_output.write(filename, file_arcname) - - logger.info('Saved %s', display_path(archive_path)) - - def install( - self, - install_options, # type: List[str] - global_options=None, # type: Optional[Sequence[str]] - root=None, # type: Optional[str] - home=None, # type: Optional[str] - prefix=None, # type: Optional[str] - warn_script_location=True, # type: bool - use_user_site=False, # type: bool - pycompile=True # type: bool - ): - # type: (...) -> None - scheme = get_scheme( - self.name, - user=use_user_site, - home=home, - root=root, - isolated=self.isolated, - prefix=prefix, - ) - - global_options = global_options if global_options is not None else [] - if self.editable: - install_editable_legacy( - install_options, - global_options, - prefix=prefix, - home=home, - use_user_site=use_user_site, - name=self.name, - setup_py_path=self.setup_py_path, - isolated=self.isolated, - build_env=self.build_env, - unpacked_source_directory=self.unpacked_source_directory, - ) - self.install_succeeded = True - return - - if self.is_wheel: - assert self.local_file_path - direct_url = None - if self.original_link: - direct_url = direct_url_from_link( - self.original_link, - self.source_dir, - self.original_link_is_in_wheel_cache, - ) - install_wheel( - self.name, - self.local_file_path, - scheme=scheme, - req_description=str(self.req), - pycompile=pycompile, - warn_script_location=warn_script_location, - direct_url=direct_url, - ) - self.install_succeeded = True - return - - # TODO: Why don't we do this for editable installs? - - # Extend the list of global and install options passed on to - # the setup.py call with the ones from the requirements file. - # Options specified in requirements file override those - # specified on the command line, since the last option given - # to setup.py is the one that is used. - global_options = list(global_options) + self.global_options - install_options = list(install_options) + self.install_options - - try: - success = install_legacy( - install_options=install_options, - global_options=global_options, - root=root, - home=home, - prefix=prefix, - use_user_site=use_user_site, - pycompile=pycompile, - scheme=scheme, - setup_py_path=self.setup_py_path, - isolated=self.isolated, - req_name=self.name, - build_env=self.build_env, - unpacked_source_directory=self.unpacked_source_directory, - req_description=str(self.req), - ) - except LegacyInstallFailure as exc: - self.install_succeeded = False - six.reraise(*exc.parent) - except Exception: - self.install_succeeded = True - raise - - self.install_succeeded = success diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/req_set.py b/env/lib/python3.8/site-packages/pip/_internal/req/req_set.py deleted file mode 100644 index f168ce17..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/req_set.py +++ /dev/null @@ -1,202 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging -from collections import OrderedDict - -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import InstallationError -from pip._internal.models.wheel import Wheel -from pip._internal.utils import compatibility_tags -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Dict, Iterable, List, Optional, Tuple - from pip._internal.req.req_install import InstallRequirement - - -logger = logging.getLogger(__name__) - - -class RequirementSet(object): - - def __init__(self, check_supported_wheels=True): - # type: (bool) -> None - """Create a RequirementSet. - """ - - self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] # noqa: E501 - self.check_supported_wheels = check_supported_wheels - - self.unnamed_requirements = [] # type: List[InstallRequirement] - - def __str__(self): - # type: () -> str - requirements = sorted( - (req for req in self.requirements.values() if not req.comes_from), - key=lambda req: canonicalize_name(req.name), - ) - return ' '.join(str(req.req) for req in requirements) - - def __repr__(self): - # type: () -> str - requirements = sorted( - self.requirements.values(), - key=lambda req: canonicalize_name(req.name), - ) - - format_string = '<{classname} object; {count} requirement(s): {reqs}>' - return format_string.format( - classname=self.__class__.__name__, - count=len(requirements), - reqs=', '.join(str(req.req) for req in requirements), - ) - - def add_unnamed_requirement(self, install_req): - # type: (InstallRequirement) -> None - assert not install_req.name - self.unnamed_requirements.append(install_req) - - def add_named_requirement(self, install_req): - # type: (InstallRequirement) -> None - assert install_req.name - - project_name = canonicalize_name(install_req.name) - self.requirements[project_name] = install_req - - def add_requirement( - self, - install_req, # type: InstallRequirement - parent_req_name=None, # type: Optional[str] - extras_requested=None # type: Optional[Iterable[str]] - ): - # type: (...) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]] # noqa: E501 - """Add install_req as a requirement to install. - - :param parent_req_name: The name of the requirement that needed this - added. The name is used because when multiple unnamed requirements - resolve to the same name, we could otherwise end up with dependency - links that point outside the Requirements set. parent_req must - already be added. Note that None implies that this is a user - supplied requirement, vs an inferred one. - :param extras_requested: an iterable of extras used to evaluate the - environment markers. - :return: Additional requirements to scan. That is either [] if - the requirement is not applicable, or [install_req] if the - requirement is applicable and has just been added. - """ - # If the markers do not match, ignore this requirement. - if not install_req.match_markers(extras_requested): - logger.info( - "Ignoring %s: markers '%s' don't match your environment", - install_req.name, install_req.markers, - ) - return [], None - - # If the wheel is not supported, raise an error. - # Should check this after filtering out based on environment markers to - # allow specifying different wheels based on the environment/OS, in a - # single requirements file. - if install_req.link and install_req.link.is_wheel: - wheel = Wheel(install_req.link.filename) - tags = compatibility_tags.get_supported() - if (self.check_supported_wheels and not wheel.supported(tags)): - raise InstallationError( - "{} is not a supported wheel on this platform.".format( - wheel.filename) - ) - - # This next bit is really a sanity check. - assert install_req.is_direct == (parent_req_name is None), ( - "a direct req shouldn't have a parent and also, " - "a non direct req should have a parent" - ) - - # Unnamed requirements are scanned again and the requirement won't be - # added as a dependency until after scanning. - if not install_req.name: - self.add_unnamed_requirement(install_req) - return [install_req], None - - try: - existing_req = self.get_requirement(install_req.name) - except KeyError: - existing_req = None - - has_conflicting_requirement = ( - parent_req_name is None and - existing_req and - not existing_req.constraint and - existing_req.extras == install_req.extras and - existing_req.req.specifier != install_req.req.specifier - ) - if has_conflicting_requirement: - raise InstallationError( - "Double requirement given: {} (already in {}, name={!r})" - .format(install_req, existing_req, install_req.name) - ) - - # When no existing requirement exists, add the requirement as a - # dependency and it will be scanned again after. - if not existing_req: - self.add_named_requirement(install_req) - # We'd want to rescan this requirement later - return [install_req], install_req - - # Assume there's no need to scan, and that we've already - # encountered this for scanning. - if install_req.constraint or not existing_req.constraint: - return [], existing_req - - does_not_satisfy_constraint = ( - install_req.link and - not ( - existing_req.link and - install_req.link.path == existing_req.link.path - ) - ) - if does_not_satisfy_constraint: - raise InstallationError( - "Could not satisfy constraints for '{}': " - "installation from path or url cannot be " - "constrained to a version".format(install_req.name) - ) - # If we're now installing a constraint, mark the existing - # object for real installation. - existing_req.constraint = False - existing_req.extras = tuple(sorted( - set(existing_req.extras) | set(install_req.extras) - )) - logger.debug( - "Setting %s extras to: %s", - existing_req, existing_req.extras, - ) - # Return the existing requirement for addition to the parent and - # scanning again. - return [existing_req], existing_req - - def has_requirement(self, name): - # type: (str) -> bool - project_name = canonicalize_name(name) - - return ( - project_name in self.requirements and - not self.requirements[project_name].constraint - ) - - def get_requirement(self, name): - # type: (str) -> InstallRequirement - project_name = canonicalize_name(name) - - if project_name in self.requirements: - return self.requirements[project_name] - - raise KeyError("No project with the name {name!r}".format(**locals())) - - @property - def all_requirements(self): - # type: () -> List[InstallRequirement] - return self.unnamed_requirements + list(self.requirements.values()) diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py b/env/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py deleted file mode 100644 index 14adeab2..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py +++ /dev/null @@ -1,151 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import contextlib -import errno -import hashlib -import logging -import os - -from pip._vendor import contextlib2 - -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from types import TracebackType - from typing import Dict, Iterator, Optional, Set, Type, Union - from pip._internal.req.req_install import InstallRequirement - from pip._internal.models.link import Link - -logger = logging.getLogger(__name__) - - -@contextlib.contextmanager -def update_env_context_manager(**changes): - # type: (str) -> Iterator[None] - target = os.environ - - # Save values from the target and change them. - non_existent_marker = object() - saved_values = {} # type: Dict[str, Union[object, str]] - for name, new_value in changes.items(): - try: - saved_values[name] = target[name] - except KeyError: - saved_values[name] = non_existent_marker - target[name] = new_value - - try: - yield - finally: - # Restore original values in the target. - for name, original_value in saved_values.items(): - if original_value is non_existent_marker: - del target[name] - else: - assert isinstance(original_value, str) # for mypy - target[name] = original_value - - -@contextlib.contextmanager -def get_requirement_tracker(): - # type: () -> Iterator[RequirementTracker] - root = os.environ.get('PIP_REQ_TRACKER') - with contextlib2.ExitStack() as ctx: - if root is None: - root = ctx.enter_context( - TempDirectory(kind='req-tracker') - ).path - ctx.enter_context(update_env_context_manager(PIP_REQ_TRACKER=root)) - logger.debug("Initialized build tracking at %s", root) - - with RequirementTracker(root) as tracker: - yield tracker - - -class RequirementTracker(object): - - def __init__(self, root): - # type: (str) -> None - self._root = root - self._entries = set() # type: Set[InstallRequirement] - logger.debug("Created build tracker: %s", self._root) - - def __enter__(self): - # type: () -> RequirementTracker - logger.debug("Entered build tracker: %s", self._root) - return self - - def __exit__( - self, - exc_type, # type: Optional[Type[BaseException]] - exc_val, # type: Optional[BaseException] - exc_tb # type: Optional[TracebackType] - ): - # type: (...) -> None - self.cleanup() - - def _entry_path(self, link): - # type: (Link) -> str - hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() - return os.path.join(self._root, hashed) - - def add(self, req): - # type: (InstallRequirement) -> None - """Add an InstallRequirement to build tracking. - """ - - # Get the file to write information about this requirement. - entry_path = self._entry_path(req.link) - - # Try reading from the file. If it exists and can be read from, a build - # is already in progress, so a LookupError is raised. - try: - with open(entry_path) as fp: - contents = fp.read() - except IOError as e: - # if the error is anything other than "file does not exist", raise. - if e.errno != errno.ENOENT: - raise - else: - message = '{} is already being built: {}'.format( - req.link, contents) - raise LookupError(message) - - # If we're here, req should really not be building already. - assert req not in self._entries - - # Start tracking this requirement. - with open(entry_path, 'w') as fp: - fp.write(str(req)) - self._entries.add(req) - - logger.debug('Added %s to build tracker %r', req, self._root) - - def remove(self, req): - # type: (InstallRequirement) -> None - """Remove an InstallRequirement from build tracking. - """ - - # Delete the created file and the corresponding entries. - os.unlink(self._entry_path(req.link)) - self._entries.remove(req) - - logger.debug('Removed %s from build tracker %r', req, self._root) - - def cleanup(self): - # type: () -> None - for req in set(self._entries): - self.remove(req) - - logger.debug("Removed build tracker: %r", self._root) - - @contextlib.contextmanager - def track(self, req): - # type: (InstallRequirement) -> Iterator[None] - self.add(req) - yield - self.remove(req) diff --git a/env/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py b/env/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py deleted file mode 100644 index 559061a6..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py +++ /dev/null @@ -1,649 +0,0 @@ -from __future__ import absolute_import - -import csv -import functools -import logging -import os -import sys -import sysconfig - -from pip._vendor import pkg_resources - -from pip._internal.exceptions import UninstallationError -from pip._internal.locations import bin_py, bin_user -from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - FakeFile, - ask, - dist_in_usersite, - dist_is_local, - egg_link_path, - is_local, - normalize_path, - renames, - rmtree, -) -from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple, - ) - from pip._vendor.pkg_resources import Distribution - -logger = logging.getLogger(__name__) - - -def _script_names(dist, script_name, is_gui): - # type: (Distribution, str, bool) -> List[str] - """Create the fully qualified name of the files created by - {console,gui}_scripts for the given ``dist``. - Returns the list of file names - """ - if dist_in_usersite(dist): - bin_dir = bin_user - else: - bin_dir = bin_py - exe_name = os.path.join(bin_dir, script_name) - paths_to_remove = [exe_name] - if WINDOWS: - paths_to_remove.append(exe_name + '.exe') - paths_to_remove.append(exe_name + '.exe.manifest') - if is_gui: - paths_to_remove.append(exe_name + '-script.pyw') - else: - paths_to_remove.append(exe_name + '-script.py') - return paths_to_remove - - -def _unique(fn): - # type: (Callable[..., Iterator[Any]]) -> Callable[..., Iterator[Any]] - @functools.wraps(fn) - def unique(*args, **kw): - # type: (Any, Any) -> Iterator[Any] - seen = set() # type: Set[Any] - for item in fn(*args, **kw): - if item not in seen: - seen.add(item) - yield item - return unique - - -@_unique -def uninstallation_paths(dist): - # type: (Distribution) -> Iterator[str] - """ - Yield all the uninstallation paths for dist based on RECORD-without-.py[co] - - Yield paths to all the files in RECORD. For each .py file in RECORD, add - the .pyc and .pyo in the same directory. - - UninstallPathSet.add() takes care of the __pycache__ .py[co]. - """ - r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) - for row in r: - path = os.path.join(dist.location, row[0]) - yield path - if path.endswith('.py'): - dn, fn = os.path.split(path) - base = fn[:-3] - path = os.path.join(dn, base + '.pyc') - yield path - path = os.path.join(dn, base + '.pyo') - yield path - - -def compact(paths): - # type: (Iterable[str]) -> Set[str] - """Compact a path set to contain the minimal number of paths - necessary to contain all paths in the set. If /a/path/ and - /a/path/to/a/file.txt are both in the set, leave only the - shorter path.""" - - sep = os.path.sep - short_paths = set() # type: Set[str] - for path in sorted(paths, key=len): - should_skip = any( - path.startswith(shortpath.rstrip("*")) and - path[len(shortpath.rstrip("*").rstrip(sep))] == sep - for shortpath in short_paths - ) - if not should_skip: - short_paths.add(path) - return short_paths - - -def compress_for_rename(paths): - # type: (Iterable[str]) -> Set[str] - """Returns a set containing the paths that need to be renamed. - - This set may include directories when the original sequence of paths - included every file on disk. - """ - case_map = dict((os.path.normcase(p), p) for p in paths) - remaining = set(case_map) - unchecked = sorted(set(os.path.split(p)[0] - for p in case_map.values()), key=len) - wildcards = set() # type: Set[str] - - def norm_join(*a): - # type: (str) -> str - return os.path.normcase(os.path.join(*a)) - - for root in unchecked: - if any(os.path.normcase(root).startswith(w) - for w in wildcards): - # This directory has already been handled. - continue - - all_files = set() # type: Set[str] - all_subdirs = set() # type: Set[str] - for dirname, subdirs, files in os.walk(root): - all_subdirs.update(norm_join(root, dirname, d) - for d in subdirs) - all_files.update(norm_join(root, dirname, f) - for f in files) - # If all the files we found are in our remaining set of files to - # remove, then remove them from the latter set and add a wildcard - # for the directory. - if not (all_files - remaining): - remaining.difference_update(all_files) - wildcards.add(root + os.sep) - - return set(map(case_map.__getitem__, remaining)) | wildcards - - -def compress_for_output_listing(paths): - # type: (Iterable[str]) -> Tuple[Set[str], Set[str]] - """Returns a tuple of 2 sets of which paths to display to user - - The first set contains paths that would be deleted. Files of a package - are not added and the top-level directory of the package has a '*' added - at the end - to signify that all it's contents are removed. - - The second set contains files that would have been skipped in the above - folders. - """ - - will_remove = set(paths) - will_skip = set() - - # Determine folders and files - folders = set() - files = set() - for path in will_remove: - if path.endswith(".pyc"): - continue - if path.endswith("__init__.py") or ".dist-info" in path: - folders.add(os.path.dirname(path)) - files.add(path) - - # probably this one https://github.com/python/mypy/issues/390 - _normcased_files = set(map(os.path.normcase, files)) # type: ignore - - folders = compact(folders) - - # This walks the tree using os.walk to not miss extra folders - # that might get added. - for folder in folders: - for dirpath, _, dirfiles in os.walk(folder): - for fname in dirfiles: - if fname.endswith(".pyc"): - continue - - file_ = os.path.join(dirpath, fname) - if (os.path.isfile(file_) and - os.path.normcase(file_) not in _normcased_files): - # We are skipping this file. Add it to the set. - will_skip.add(file_) - - will_remove = files | { - os.path.join(folder, "*") for folder in folders - } - - return will_remove, will_skip - - -class StashedUninstallPathSet(object): - """A set of file rename operations to stash files while - tentatively uninstalling them.""" - def __init__(self): - # type: () -> None - # Mapping from source file root to [Adjacent]TempDirectory - # for files under that directory. - self._save_dirs = {} # type: Dict[str, TempDirectory] - # (old path, new path) tuples for each move that may need - # to be undone. - self._moves = [] # type: List[Tuple[str, str]] - - def _get_directory_stash(self, path): - # type: (str) -> str - """Stashes a directory. - - Directories are stashed adjacent to their original location if - possible, or else moved/copied into the user's temp dir.""" - - try: - save_dir = AdjacentTempDirectory(path) # type: TempDirectory - except OSError: - save_dir = TempDirectory(kind="uninstall") - self._save_dirs[os.path.normcase(path)] = save_dir - - return save_dir.path - - def _get_file_stash(self, path): - # type: (str) -> str - """Stashes a file. - - If no root has been provided, one will be created for the directory - in the user's temp directory.""" - path = os.path.normcase(path) - head, old_head = os.path.dirname(path), None - save_dir = None - - while head != old_head: - try: - save_dir = self._save_dirs[head] - break - except KeyError: - pass - head, old_head = os.path.dirname(head), head - else: - # Did not find any suitable root - head = os.path.dirname(path) - save_dir = TempDirectory(kind='uninstall') - self._save_dirs[head] = save_dir - - relpath = os.path.relpath(path, head) - if relpath and relpath != os.path.curdir: - return os.path.join(save_dir.path, relpath) - return save_dir.path - - def stash(self, path): - # type: (str) -> str - """Stashes the directory or file and returns its new location. - Handle symlinks as files to avoid modifying the symlink targets. - """ - path_is_dir = os.path.isdir(path) and not os.path.islink(path) - if path_is_dir: - new_path = self._get_directory_stash(path) - else: - new_path = self._get_file_stash(path) - - self._moves.append((path, new_path)) - if (path_is_dir and os.path.isdir(new_path)): - # If we're moving a directory, we need to - # remove the destination first or else it will be - # moved to inside the existing directory. - # We just created new_path ourselves, so it will - # be removable. - os.rmdir(new_path) - renames(path, new_path) - return new_path - - def commit(self): - # type: () -> None - """Commits the uninstall by removing stashed files.""" - for _, save_dir in self._save_dirs.items(): - save_dir.cleanup() - self._moves = [] - self._save_dirs = {} - - def rollback(self): - # type: () -> None - """Undoes the uninstall by moving stashed files back.""" - for p in self._moves: - logger.info("Moving to %s\n from %s", *p) - - for new_path, path in self._moves: - try: - logger.debug('Replacing %s from %s', new_path, path) - if os.path.isfile(new_path) or os.path.islink(new_path): - os.unlink(new_path) - elif os.path.isdir(new_path): - rmtree(new_path) - renames(path, new_path) - except OSError as ex: - logger.error("Failed to restore %s", new_path) - logger.debug("Exception: %s", ex) - - self.commit() - - @property - def can_rollback(self): - # type: () -> bool - return bool(self._moves) - - -class UninstallPathSet(object): - """A set of file paths to be removed in the uninstallation of a - requirement.""" - def __init__(self, dist): - # type: (Distribution) -> None - self.paths = set() # type: Set[str] - self._refuse = set() # type: Set[str] - self.pth = {} # type: Dict[str, UninstallPthEntries] - self.dist = dist - self._moved_paths = StashedUninstallPathSet() - - def _permitted(self, path): - # type: (str) -> bool - """ - Return True if the given path is one we are permitted to - remove/modify, False otherwise. - - """ - return is_local(path) - - def add(self, path): - # type: (str) -> None - head, tail = os.path.split(path) - - # we normalize the head to resolve parent directory symlinks, but not - # the tail, since we only want to uninstall symlinks, not their targets - path = os.path.join(normalize_path(head), os.path.normcase(tail)) - - if not os.path.exists(path): - return - if self._permitted(path): - self.paths.add(path) - else: - self._refuse.add(path) - - # __pycache__ files can show up after 'installed-files.txt' is created, - # due to imports - if os.path.splitext(path)[1] == '.py' and uses_pycache: - self.add(cache_from_source(path)) - - def add_pth(self, pth_file, entry): - # type: (str, str) -> None - pth_file = normalize_path(pth_file) - if self._permitted(pth_file): - if pth_file not in self.pth: - self.pth[pth_file] = UninstallPthEntries(pth_file) - self.pth[pth_file].add(entry) - else: - self._refuse.add(pth_file) - - def remove(self, auto_confirm=False, verbose=False): - # type: (bool, bool) -> None - """Remove paths in ``self.paths`` with confirmation (unless - ``auto_confirm`` is True).""" - - if not self.paths: - logger.info( - "Can't uninstall '%s'. No files were found to uninstall.", - self.dist.project_name, - ) - return - - dist_name_version = ( - self.dist.project_name + "-" + self.dist.version - ) - logger.info('Uninstalling %s:', dist_name_version) - - with indent_log(): - if auto_confirm or self._allowed_to_proceed(verbose): - moved = self._moved_paths - - for_rename = compress_for_rename(self.paths) - - for path in sorted(compact(for_rename)): - moved.stash(path) - logger.debug('Removing file or directory %s', path) - - for pth in self.pth.values(): - pth.remove() - - logger.info('Successfully uninstalled %s', dist_name_version) - - def _allowed_to_proceed(self, verbose): - # type: (bool) -> bool - """Display which files would be deleted and prompt for confirmation - """ - - def _display(msg, paths): - # type: (str, Iterable[str]) -> None - if not paths: - return - - logger.info(msg) - with indent_log(): - for path in sorted(compact(paths)): - logger.info(path) - - if not verbose: - will_remove, will_skip = compress_for_output_listing(self.paths) - else: - # In verbose mode, display all the files that are going to be - # deleted. - will_remove = set(self.paths) - will_skip = set() - - _display('Would remove:', will_remove) - _display('Would not remove (might be manually added):', will_skip) - _display('Would not remove (outside of prefix):', self._refuse) - if verbose: - _display('Will actually move:', compress_for_rename(self.paths)) - - return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' - - def rollback(self): - # type: () -> None - """Rollback the changes previously made by remove().""" - if not self._moved_paths.can_rollback: - logger.error( - "Can't roll back %s; was not uninstalled", - self.dist.project_name, - ) - return - logger.info('Rolling back uninstall of %s', self.dist.project_name) - self._moved_paths.rollback() - for pth in self.pth.values(): - pth.rollback() - - def commit(self): - # type: () -> None - """Remove temporary save dir: rollback will no longer be possible.""" - self._moved_paths.commit() - - @classmethod - def from_dist(cls, dist): - # type: (Distribution) -> UninstallPathSet - dist_path = normalize_path(dist.location) - if not dist_is_local(dist): - logger.info( - "Not uninstalling %s at %s, outside environment %s", - dist.key, - dist_path, - sys.prefix, - ) - return cls(dist) - - if dist_path in {p for p in {sysconfig.get_path("stdlib"), - sysconfig.get_path("platstdlib")} - if p}: - logger.info( - "Not uninstalling %s at %s, as it is in the standard library.", - dist.key, - dist_path, - ) - return cls(dist) - - paths_to_remove = cls(dist) - develop_egg_link = egg_link_path(dist) - develop_egg_link_egg_info = '{}.egg-info'.format( - pkg_resources.to_filename(dist.project_name)) - egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) - # Special case for distutils installed package - distutils_egg_info = getattr(dist._provider, 'path', None) - - # Uninstall cases order do matter as in the case of 2 installs of the - # same package, pip needs to uninstall the currently detected version - if (egg_info_exists and dist.egg_info.endswith('.egg-info') and - not dist.egg_info.endswith(develop_egg_link_egg_info)): - # if dist.egg_info.endswith(develop_egg_link_egg_info), we - # are in fact in the develop_egg_link case - paths_to_remove.add(dist.egg_info) - if dist.has_metadata('installed-files.txt'): - for installed_file in dist.get_metadata( - 'installed-files.txt').splitlines(): - path = os.path.normpath( - os.path.join(dist.egg_info, installed_file) - ) - paths_to_remove.add(path) - # FIXME: need a test for this elif block - # occurs with --single-version-externally-managed/--record outside - # of pip - elif dist.has_metadata('top_level.txt'): - if dist.has_metadata('namespace_packages.txt'): - namespaces = dist.get_metadata('namespace_packages.txt') - else: - namespaces = [] - for top_level_pkg in [ - p for p - in dist.get_metadata('top_level.txt').splitlines() - if p and p not in namespaces]: - path = os.path.join(dist.location, top_level_pkg) - paths_to_remove.add(path) - paths_to_remove.add(path + '.py') - paths_to_remove.add(path + '.pyc') - paths_to_remove.add(path + '.pyo') - - elif distutils_egg_info: - raise UninstallationError( - "Cannot uninstall {!r}. It is a distutils installed project " - "and thus we cannot accurately determine which files belong " - "to it which would lead to only a partial uninstall.".format( - dist.project_name, - ) - ) - - elif dist.location.endswith('.egg'): - # package installed by easy_install - # We cannot match on dist.egg_name because it can slightly vary - # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg - paths_to_remove.add(dist.location) - easy_install_egg = os.path.split(dist.location)[1] - easy_install_pth = os.path.join(os.path.dirname(dist.location), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) - - elif egg_info_exists and dist.egg_info.endswith('.dist-info'): - for path in uninstallation_paths(dist): - paths_to_remove.add(path) - - elif develop_egg_link: - # develop egg - with open(develop_egg_link, 'r') as fh: - link_pointer = os.path.normcase(fh.readline().strip()) - assert (link_pointer == dist.location), ( - 'Egg-link {} does not match installed location of {} ' - '(at {})'.format( - link_pointer, dist.project_name, dist.location) - ) - paths_to_remove.add(develop_egg_link) - easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, dist.location) - - else: - logger.debug( - 'Not sure how to uninstall: %s - Check: %s', - dist, dist.location, - ) - - # find distutils scripts= scripts - if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): - for script in dist.metadata_listdir('scripts'): - if dist_in_usersite(dist): - bin_dir = bin_user - else: - bin_dir = bin_py - paths_to_remove.add(os.path.join(bin_dir, script)) - if WINDOWS: - paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') - - # find console_scripts - _scripts_to_remove = [] - console_scripts = dist.get_entry_map(group='console_scripts') - for name in console_scripts.keys(): - _scripts_to_remove.extend(_script_names(dist, name, False)) - # find gui_scripts - gui_scripts = dist.get_entry_map(group='gui_scripts') - for name in gui_scripts.keys(): - _scripts_to_remove.extend(_script_names(dist, name, True)) - - for s in _scripts_to_remove: - paths_to_remove.add(s) - - return paths_to_remove - - -class UninstallPthEntries(object): - def __init__(self, pth_file): - # type: (str) -> None - self.file = pth_file - self.entries = set() # type: Set[str] - self._saved_lines = None # type: Optional[List[bytes]] - - def add(self, entry): - # type: (str) -> None - entry = os.path.normcase(entry) - # On Windows, os.path.normcase converts the entry to use - # backslashes. This is correct for entries that describe absolute - # paths outside of site-packages, but all the others use forward - # slashes. - # os.path.splitdrive is used instead of os.path.isabs because isabs - # treats non-absolute paths with drive letter markings like c:foo\bar - # as absolute paths. It also does not recognize UNC paths if they don't - # have more than "\\sever\share". Valid examples: "\\server\share\" or - # "\\server\share\folder". Python 2.7.8+ support UNC in splitdrive. - if WINDOWS and not os.path.splitdrive(entry)[0]: - entry = entry.replace('\\', '/') - self.entries.add(entry) - - def remove(self): - # type: () -> None - logger.debug('Removing pth entries from %s:', self.file) - - # If the file doesn't exist, log a warning and return - if not os.path.isfile(self.file): - logger.warning( - "Cannot remove entries from nonexistent file {}".format( - self.file) - ) - return - with open(self.file, 'rb') as fh: - # windows uses '\r\n' with py3k, but uses '\n' with py2.x - lines = fh.readlines() - self._saved_lines = lines - if any(b'\r\n' in line for line in lines): - endline = '\r\n' - else: - endline = '\n' - # handle missing trailing newline - if lines and not lines[-1].endswith(endline.encode("utf-8")): - lines[-1] = lines[-1] + endline.encode("utf-8") - for entry in self.entries: - try: - logger.debug('Removing entry: %s', entry) - lines.remove((entry + endline).encode("utf-8")) - except ValueError: - pass - with open(self.file, 'wb') as fh: - fh.writelines(lines) - - def rollback(self): - # type: () -> bool - if self._saved_lines is None: - logger.error( - 'Cannot roll back changes to %s, none were made', self.file - ) - return False - logger.debug('Rolling %s back to previous state', self.file) - with open(self.file, 'wb') as fh: - fh.writelines(self._saved_lines) - return True diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index edf1bbdee0d1280073ed77fd441a40d50e90d4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmWIL<>g`kf{3<5@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vNza+OnzaXszgUf)+D}dhk72dJw;(j zEB>W?2A|*s!wwY|n@RG?8 zmM{FIE87Pwj(*||EaqezRI0d?$_bXi)VVQSpk zJfcRaTs6(!qt- z4!ydj RequirementSet - raise NotImplementedError() - - def get_installation_order(self, req_set): - # type: (RequirementSet) -> List[InstallRequirement] - raise NotImplementedError() diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index f3607244361a2dbf394ad3d06f665b8e6789e530..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py deleted file mode 100644 index cdb44d19..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/legacy/resolver.py +++ /dev/null @@ -1,459 +0,0 @@ -"""Dependency Resolution - -The dependency resolution in pip is performed as follows: - -for top-level requirements: - a. only one spec allowed per project, regardless of conflicts or not. - otherwise a "double requirement" exception is raised - b. they override sub-dependency requirements. -for sub-dependencies - a. "first found, wins" (where the order is breadth first) -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -import logging -import sys -from collections import defaultdict -from itertools import chain - -from pip._vendor.packaging import specifiers - -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, - DistributionNotFound, - HashError, - HashErrors, - UnsupportedPythonVersion, -) -from pip._internal.req.req_set import RequirementSet -from pip._internal.resolution.base import BaseResolver -from pip._internal.utils.compatibility_tags import get_supported -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import dist_in_usersite, normalize_version_info -from pip._internal.utils.packaging import ( - check_requires_python, - get_requires_python, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import DefaultDict, List, Optional, Set, Tuple - from pip._vendor import pkg_resources - - from pip._internal.cache import WheelCache - from pip._internal.distributions import AbstractDistribution - from pip._internal.index.package_finder import PackageFinder - from pip._internal.operations.prepare import RequirementPreparer - from pip._internal.req.req_install import InstallRequirement - from pip._internal.resolution.base import InstallRequirementProvider - - DiscoveredDependencies = DefaultDict[str, List[InstallRequirement]] - -logger = logging.getLogger(__name__) - - -def _check_dist_requires_python( - dist, # type: pkg_resources.Distribution - version_info, # type: Tuple[int, int, int] - ignore_requires_python=False, # type: bool -): - # type: (...) -> None - """ - Check whether the given Python version is compatible with a distribution's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - - :raises UnsupportedPythonVersion: When the given Python version isn't - compatible. - """ - requires_python = get_requires_python(dist) - try: - is_compatible = check_requires_python( - requires_python, version_info=version_info, - ) - except specifiers.InvalidSpecifier as exc: - logger.warning( - "Package %r has an invalid Requires-Python: %s", - dist.project_name, exc, - ) - return - - if is_compatible: - return - - version = '.'.join(map(str, version_info)) - if ignore_requires_python: - logger.debug( - 'Ignoring failed Requires-Python check for package %r: ' - '%s not in %r', - dist.project_name, version, requires_python, - ) - return - - raise UnsupportedPythonVersion( - 'Package {!r} requires a different Python: {} not in {!r}'.format( - dist.project_name, version, requires_python, - )) - - -class Resolver(BaseResolver): - """Resolves which packages need to be installed/uninstalled to perform \ - the requested operation without breaking the requirements of any package. - """ - - _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} - - def __init__( - self, - preparer, # type: RequirementPreparer - finder, # type: PackageFinder - wheel_cache, # type: Optional[WheelCache] - make_install_req, # type: InstallRequirementProvider - use_user_site, # type: bool - ignore_dependencies, # type: bool - ignore_installed, # type: bool - ignore_requires_python, # type: bool - force_reinstall, # type: bool - upgrade_strategy, # type: str - py_version_info=None, # type: Optional[Tuple[int, ...]] - ): - # type: (...) -> None - super(Resolver, self).__init__() - assert upgrade_strategy in self._allowed_strategies - - if py_version_info is None: - py_version_info = sys.version_info[:3] - else: - py_version_info = normalize_version_info(py_version_info) - - self._py_version_info = py_version_info - - self.preparer = preparer - self.finder = finder - self.wheel_cache = wheel_cache - - self.upgrade_strategy = upgrade_strategy - self.force_reinstall = force_reinstall - self.ignore_dependencies = ignore_dependencies - self.ignore_installed = ignore_installed - self.ignore_requires_python = ignore_requires_python - self.use_user_site = use_user_site - self._make_install_req = make_install_req - - self._discovered_dependencies = \ - defaultdict(list) # type: DiscoveredDependencies - - def resolve(self, root_reqs, check_supported_wheels): - # type: (List[InstallRequirement], bool) -> RequirementSet - """Resolve what operations need to be done - - As a side-effect of this method, the packages (and their dependencies) - are downloaded, unpacked and prepared for installation. This - preparation is done by ``pip.operations.prepare``. - - Once PyPI has static dependency metadata available, it would be - possible to move the preparation to become a step separated from - dependency resolution. - """ - requirement_set = RequirementSet( - check_supported_wheels=check_supported_wheels - ) - for req in root_reqs: - requirement_set.add_requirement(req) - - # Actually prepare the files, and collect any exceptions. Most hash - # exceptions cannot be checked ahead of time, because - # _populate_link() needs to be called before we can make decisions - # based on link type. - discovered_reqs = [] # type: List[InstallRequirement] - hash_errors = HashErrors() - for req in chain(root_reqs, discovered_reqs): - try: - discovered_reqs.extend(self._resolve_one(requirement_set, req)) - except HashError as exc: - exc.req = req - hash_errors.append(exc) - - if hash_errors: - raise hash_errors - - return requirement_set - - def _is_upgrade_allowed(self, req): - # type: (InstallRequirement) -> bool - if self.upgrade_strategy == "to-satisfy-only": - return False - elif self.upgrade_strategy == "eager": - return True - else: - assert self.upgrade_strategy == "only-if-needed" - return req.is_direct - - def _set_req_to_reinstall(self, req): - # type: (InstallRequirement) -> None - """ - Set a requirement to be installed. - """ - # Don't uninstall the conflict if doing a user install and the - # conflict is not a user install. - if not self.use_user_site or dist_in_usersite(req.satisfied_by): - req.should_reinstall = True - req.satisfied_by = None - - def _check_skip_installed(self, req_to_install): - # type: (InstallRequirement) -> Optional[str] - """Check if req_to_install should be skipped. - - This will check if the req is installed, and whether we should upgrade - or reinstall it, taking into account all the relevant user options. - - After calling this req_to_install will only have satisfied_by set to - None if the req_to_install is to be upgraded/reinstalled etc. Any - other value will be a dist recording the current thing installed that - satisfies the requirement. - - Note that for vcs urls and the like we can't assess skipping in this - routine - we simply identify that we need to pull the thing down, - then later on it is pulled down and introspected to assess upgrade/ - reinstalls etc. - - :return: A text reason for why it was skipped, or None. - """ - if self.ignore_installed: - return None - - req_to_install.check_if_exists(self.use_user_site) - if not req_to_install.satisfied_by: - return None - - if self.force_reinstall: - self._set_req_to_reinstall(req_to_install) - return None - - if not self._is_upgrade_allowed(req_to_install): - if self.upgrade_strategy == "only-if-needed": - return 'already satisfied, skipping upgrade' - return 'already satisfied' - - # Check for the possibility of an upgrade. For link-based - # requirements we have to pull the tree down and inspect to assess - # the version #, so it's handled way down. - if not req_to_install.link: - try: - self.finder.find_requirement(req_to_install, upgrade=True) - except BestVersionAlreadyInstalled: - # Then the best version is installed. - return 'already up-to-date' - except DistributionNotFound: - # No distribution found, so we squash the error. It will - # be raised later when we re-try later to do the install. - # Why don't we just raise here? - pass - - self._set_req_to_reinstall(req_to_install) - return None - - def _populate_link(self, req): - # type: (InstallRequirement) -> None - """Ensure that if a link can be found for this, that it is found. - - Note that req.link may still be None - if the requirement is already - installed and not needed to be upgraded based on the return value of - _is_upgrade_allowed(). - - If preparer.require_hashes is True, don't use the wheel cache, because - cached wheels, always built locally, have different hashes than the - files downloaded from the index server and thus throw false hash - mismatches. Furthermore, cached wheels at present have undeterministic - contents due to file modification times. - """ - upgrade = self._is_upgrade_allowed(req) - if req.link is None: - req.link = self.finder.find_requirement(req, upgrade) - - if self.wheel_cache is None or self.preparer.require_hashes: - return - cache_entry = self.wheel_cache.get_cache_entry( - link=req.link, - package_name=req.name, - supported_tags=get_supported(), - ) - if cache_entry is not None: - logger.debug('Using cached wheel link: %s', cache_entry.link) - if req.link is req.original_link and cache_entry.persistent: - req.original_link_is_in_wheel_cache = True - req.link = cache_entry.link - - def _get_abstract_dist_for(self, req): - # type: (InstallRequirement) -> AbstractDistribution - """Takes a InstallRequirement and returns a single AbstractDist \ - representing a prepared variant of the same. - """ - if req.editable: - return self.preparer.prepare_editable_requirement(req) - - # satisfied_by is only evaluated by calling _check_skip_installed, - # so it must be None here. - assert req.satisfied_by is None - skip_reason = self._check_skip_installed(req) - - if req.satisfied_by: - return self.preparer.prepare_installed_requirement( - req, skip_reason - ) - - # We eagerly populate the link, since that's our "legacy" behavior. - self._populate_link(req) - abstract_dist = self.preparer.prepare_linked_requirement(req) - - # NOTE - # The following portion is for determining if a certain package is - # going to be re-installed/upgraded or not and reporting to the user. - # This should probably get cleaned up in a future refactor. - - # req.req is only avail after unpack for URL - # pkgs repeat check_if_exists to uninstall-on-upgrade - # (#14) - if not self.ignore_installed: - req.check_if_exists(self.use_user_site) - - if req.satisfied_by: - should_modify = ( - self.upgrade_strategy != "to-satisfy-only" or - self.force_reinstall or - self.ignore_installed or - req.link.scheme == 'file' - ) - if should_modify: - self._set_req_to_reinstall(req) - else: - logger.info( - 'Requirement already satisfied (use --upgrade to upgrade):' - ' %s', req, - ) - - return abstract_dist - - def _resolve_one( - self, - requirement_set, # type: RequirementSet - req_to_install, # type: InstallRequirement - ): - # type: (...) -> List[InstallRequirement] - """Prepare a single requirements file. - - :return: A list of additional InstallRequirements to also install. - """ - # Tell user what we are doing for this requirement: - # obtain (editable), skipping, processing (local url), collecting - # (remote url or package name) - if req_to_install.constraint or req_to_install.prepared: - return [] - - req_to_install.prepared = True - - abstract_dist = self._get_abstract_dist_for(req_to_install) - - # Parse and return dependencies - dist = abstract_dist.get_pkg_resources_distribution() - # This will raise UnsupportedPythonVersion if the given Python - # version isn't compatible with the distribution's Requires-Python. - _check_dist_requires_python( - dist, version_info=self._py_version_info, - ignore_requires_python=self.ignore_requires_python, - ) - - more_reqs = [] # type: List[InstallRequirement] - - def add_req(subreq, extras_requested): - sub_install_req = self._make_install_req( - str(subreq), - req_to_install, - ) - parent_req_name = req_to_install.name - to_scan_again, add_to_parent = requirement_set.add_requirement( - sub_install_req, - parent_req_name=parent_req_name, - extras_requested=extras_requested, - ) - if parent_req_name and add_to_parent: - self._discovered_dependencies[parent_req_name].append( - add_to_parent - ) - more_reqs.extend(to_scan_again) - - with indent_log(): - # We add req_to_install before its dependencies, so that we - # can refer to it when adding dependencies. - if not requirement_set.has_requirement(req_to_install.name): - # 'unnamed' requirements will get added here - # 'unnamed' requirements can only come from being directly - # provided by the user. - assert req_to_install.is_direct - requirement_set.add_requirement( - req_to_install, parent_req_name=None, - ) - - if not self.ignore_dependencies: - if req_to_install.extras: - logger.debug( - "Installing extra requirements: %r", - ','.join(req_to_install.extras), - ) - missing_requested = sorted( - set(req_to_install.extras) - set(dist.extras) - ) - for missing in missing_requested: - logger.warning( - '%s does not provide the extra \'%s\'', - dist, missing - ) - - available_requested = sorted( - set(dist.extras) & set(req_to_install.extras) - ) - for subreq in dist.requires(available_requested): - add_req(subreq, extras_requested=available_requested) - - if not req_to_install.editable and not req_to_install.satisfied_by: - # XXX: --no-install leads this to report 'Successfully - # downloaded' for only non-editable reqs, even though we took - # action on them. - req_to_install.successfully_downloaded = True - - return more_reqs - - def get_installation_order(self, req_set): - # type: (RequirementSet) -> List[InstallRequirement] - """Create the installation order. - - The installation order is topological - requirements are installed - before the requiring thing. We break cycles at an arbitrary point, - and make no other guarantees. - """ - # The current implementation, which we may change at any point - # installs the user specified things in the order given, except when - # dependencies must come earlier to achieve topological order. - order = [] - ordered_reqs = set() # type: Set[InstallRequirement] - - def schedule(req): - if req.satisfied_by or req in ordered_reqs: - return - if req.constraint: - return - ordered_reqs.add(req) - for dep in self._discovered_dependencies[req.name]: - schedule(dep) - order.append(req) - - for install_req in req_set.requirements.values(): - schedule(install_req) - return order diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index d9c1682570f90641081484dd6ccbadfbe814ddab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmWIL<>g`kf{3<5@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o10Cza+OnzaX<{9 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc deleted file mode 100644 index b886a290ba15fb01f9b84b824305b6e9487e725e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2229 zcmb_eTW{Mo6ecNImM=-%E?a|S?b7aQpizcxF9U+0Sk|?{R&}V+V%1OxvdJXsbPFkG zwVS-m!G1^kn7^@~!H2!2=fw==+r3_QNa>(@L@QtSyMr&gg9z7F{V>Uegy>hLP-)c1 zRE&pvA_}{!T?p052D-MkEfVn}lj|+?2TN@dMus=GQW*z%kz!{pN+IKF-8mK>S}zZN zetGch4ZRJiwp1!}!L>Esq|N7Pn818Blj(EO%e5t5$rUWc%}$xOlH8eZj{Vo zw8{oTm`P1~mCAQv+{1}-!(85hu08`Ih(|f`m@vkL8Bx#V1~&m|6<*;Md;xcmU0XLw z)jw4rEEZ34fkpwzP3N&69BPWObAAr}D9cic4JjI*c! zmEd=!OeIX4N<>>{gEbMq7?VPC#2B_pE;+b(dB5Z}&>$C(EFwX_OL=W>g$ehepuHWT zP+)A54HwEL%R;9P0Q!e%DN=$M;S_Sn-0un#Z6=psPS>EiJmdiY?~M7mQ28pzL$wtO z?so?_Kz!=KQrUwua&Eh-ZNC7a@9Vnn$0_ee0>(|>-|YtxCJ8tjfR+iF59IrxSzbr- z0g@9xiVj~Z9<~5y1-bxdC46xka8~6t$WdL_Hl|s* zd^Hhe^A9JeS`L$CH9_2k6)pn*2&0-{Y4+Ic|3%Wrpyfh4x(Z(51=%jyx^iM`vU>SY z<$s%NZHwIJA`=OR8$1-sIkwA&izjx^ioG=luA$~|{9gF-4e2{^d#51j}2?PHCMB;lVt3bT#r}se)9O%=WNW7sZGXJtZ wL4&NJGQ8=um3Hw(D2|&%-_HwI+iT;4zK)lU!k4MZn(zwDvnFjCw%wZh2RTvkN&o-= diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc deleted file mode 100644 index 45e20643a1886fcb15ec076410ef6efc625d434e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13326 zcmcIqNpRd&dIr$wh0W$7YTsyBwk)?tqAbatMV2&@W!ct@hjv-^*zOsp-E4qlljubc zpk=nGnW~{Do+RZ%=HNpr2Qrl$R5_(8RjEqlkjg2QdoDb9S67Agg)XZ^8eu~KY~SH|Tz=a-rjl?kcm{mJH3 zWlHJ=f4aG+vPbG;{!DXkWiRSQcii9C++W$>JWx4c8s1*@KbWiJA8a0~9BLk}9Bv+| z9BCe{9Bm$}9BUr09GCtRn18l1EA>hLv8GdTq(0?8-aJt`A@ynhiRP1)Cs8lDdoahz z%1Nou_)j%YRZd~9=VR`1JRkSY;`v!T&$^G{`7wDuhiAuq9M6wS`}24{;XZ-qC*=78 zo}YA2;`yXJKj)gajPg^Tb9Ls+Ry2LH^Y{2ltDf5kYYV;??SJ5t-)OP>%uU_r zP4D(vLwQZF#hDJY+N!Ci`A`pEZL}8K__BA&3pqX;2i4AcxQwYW%un8Xqr&T*5a8GRsBjCzdab$_ zWq@y#eQT`)$g^*^h@BagsxQ_8FTobiFExTtH5S&`9pCp|TflRz9uB>?Uu(2h@qK&{ z#r(@?+E(l3Omz5~ue_SO9+Sdzdl2ur5mT`DYJ%gXk9CXd7ynov$8{Z7a0$hRxniiv z&~(jB^H*kQZ5S&Vyt8p-apiF3!ve}NTt!^tuJvig&3u{zYuNMMnNCe%MVv<9BujZe z6HO(H*%s0T(d3ffUa0xiy{OO#+CG-V zWeaeCsx?|+l#d4}m!d*4Uo?3w2s}k1-%zTpR33OmnKk9BCs0#QvN*}&DSoisMmXiJ&Ba-M1nee773qG+y@&^(-2F@#fjE**V*3bk3}`I<@+$=bpKW7}+SU6ix_$-*~tVc(hwN(#YhIRy}FJsQ&2nxfR zG%eFk|Kj?W_800rzCLdtSZOi85Sc*uD-($ zDaF-kKAvGg+UnvQYSHXyiX;nt5p5ntl?!MyK$Q$$q#XY;9zv*;t(em{P4K(DZGo>- zZb!WkrreIFQo`}~usb%a>coa6y#Gb+?!C*G@80Vp$)x7JoR%Vrsw^sXRC~p%Ync*F zf~JAzR%4;HTXIFEpcXa)2wk_jK#2e@#-2FK32X?u+ry;Xfw|c0$LJJr1r3YrR50zY zEIVPbl)?ThHo%p2vCp0@PJCtNVJ4+>R? zg+^Gd)(B<^g)x>hlfUkF9*y-}GD4j?F8Q%eo)qj4q2faNV+WWkRtO5L*qbJJo!p(7 z?;f~Y_iI5QxZQjDF2&O0>RuW8ve^3|xRtZ&c?=efRjc|-6||6k)oPRhn@X$ursBNA zjEa`Z>!@n=Ha-Rg6ozF3*TPr3#8dYk*z;UrGO6Hs43$vUdBxnc)FI%>{cf!SPqNW{ zYyM?ysA3}!Q4H;_Zla5Z*%FweY&%@`)G+9|Y87To^&_+ngvqRuSu(rjT`doL?hG{7 ze8boR*xP0a?58f{1t|C?A$xXtvkrNPS-&7#?TW*6YaGGJ#2$qQ6kG|(uD%GP{$-|Oh68m{LwT28RG zAo~s`gtri`C}2 z-J|p5_GTl1+fZM==-h>nbUqB^-ktra_Dy#9UM{K^K>+m*ifER8OJ{Wn;xK5hsXB~e z(ebhWpzW-yY)%obw+Y3r=1sC?IhIxvgG)NNjUbximH!M~0%|nFDw?)c0K?9V7rwTv z>96bz>;a?rwe_W)=bKXeCWkk>6U*@&11nGUlS-CJJW#@I8zwmbf>`f0OI7ei(`5wX z$|n44vQ>{j8N#r8L zC^3nqV2|`WzOX>xtVgCdBuugYN4UvVHWttRZ!uVGY8PoC!U-vv)4aogu)el4hs^G- z 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 C(syG3 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc deleted file mode 100644 index d5822d5198ebd191e87bc410cfae44318b65817e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1915 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 N{IRaJa&zUqKLAeLz108! diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc deleted file mode 100644 index 247ebc336ff34ac42e4dbe76550a61726a577be7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5497 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/base.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/base.py deleted file mode 100644 index 5f99618c..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/base.py +++ /dev/null @@ -1,52 +0,0 @@ -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Sequence, Set - - from pip._internal.req.req_install import InstallRequirement - from pip._vendor.packaging.version import _BaseVersion - - -def format_name(project, extras): - # type: (str, Set[str]) -> str - if not extras: - return project - canonical_extras = sorted(canonicalize_name(e) for e in extras) - return "{}[{}]".format(project, ",".join(canonical_extras)) - - -class Requirement(object): - @property - def name(self): - # type: () -> str - raise NotImplementedError("Subclass should override") - - def find_matches(self): - # type: () -> Sequence[Candidate] - raise NotImplementedError("Subclass should override") - - def is_satisfied_by(self, candidate): - # type: (Candidate) -> bool - return False - - -class Candidate(object): - @property - def name(self): - # type: () -> str - raise NotImplementedError("Override in subclass") - - @property - def version(self): - # type: () -> _BaseVersion - raise NotImplementedError("Override in subclass") - - def get_dependencies(self): - # type: () -> Sequence[Requirement] - raise NotImplementedError("Override in subclass") - - def get_install_requirement(self): - # type: () -> Optional[InstallRequirement] - raise NotImplementedError("Override in subclass") diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/candidates.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/candidates.py deleted file mode 100644 index f8461ade..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/candidates.py +++ /dev/null @@ -1,450 +0,0 @@ -import logging -import sys - -from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import Version - -from pip._internal.req.constructors import ( - install_req_from_editable, - install_req_from_line, -) -from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.misc import normalize_version_info -from pip._internal.utils.packaging import get_requires_python -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -from .base import Candidate, format_name - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional, Sequence, Set, Tuple, Union - - from pip._vendor.packaging.version import _BaseVersion - from pip._vendor.pkg_resources import Distribution - - from pip._internal.distributions import AbstractDistribution - from pip._internal.models.link import Link - - from .base import Requirement - from .factory import Factory - - BaseCandidate = Union[ - "AlreadyInstalledCandidate", - "EditableCandidate", - "LinkCandidate", - ] - - -logger = logging.getLogger(__name__) - - -def make_install_req_from_link(link, parent): - # type: (Link, InstallRequirement) -> InstallRequirement - assert not parent.editable, "parent is editable" - return install_req_from_line( - link.url, - comes_from=parent.comes_from, - use_pep517=parent.use_pep517, - isolated=parent.isolated, - constraint=parent.constraint, - options=dict( - install_options=parent.install_options, - global_options=parent.global_options, - hashes=parent.hash_options - ), - ) - - -def make_install_req_from_editable(link, parent): - # type: (Link, InstallRequirement) -> InstallRequirement - assert parent.editable, "parent not editable" - return install_req_from_editable( - link.url, - comes_from=parent.comes_from, - use_pep517=parent.use_pep517, - isolated=parent.isolated, - constraint=parent.constraint, - options=dict( - install_options=parent.install_options, - global_options=parent.global_options, - hashes=parent.hash_options - ), - ) - - -def make_install_req_from_dist(dist, parent): - # type: (Distribution, InstallRequirement) -> InstallRequirement - ireq = install_req_from_line( - "{}=={}".format( - canonicalize_name(dist.project_name), - dist.parsed_version, - ), - comes_from=parent.comes_from, - use_pep517=parent.use_pep517, - isolated=parent.isolated, - constraint=parent.constraint, - options=dict( - install_options=parent.install_options, - global_options=parent.global_options, - hashes=parent.hash_options - ), - ) - ireq.satisfied_by = dist - return ireq - - -class _InstallRequirementBackedCandidate(Candidate): - def __init__( - self, - link, # type: Link - ireq, # type: InstallRequirement - factory, # type: Factory - name=None, # type: Optional[str] - version=None, # type: Optional[_BaseVersion] - ): - # type: (...) -> None - self.link = link - self._factory = factory - self._ireq = ireq - self._name = name - self._version = version - self._dist = None # type: Optional[Distribution] - - def __repr__(self): - # type: () -> str - return "{class_name}({link!r})".format( - class_name=self.__class__.__name__, - link=str(self.link), - ) - - def __eq__(self, other): - # type: (Any) -> bool - if isinstance(other, self.__class__): - return self.link == other.link - return False - - # Needed for Python 2, which does not implement this by default - def __ne__(self, other): - # type: (Any) -> bool - return not self.__eq__(other) - - @property - def name(self): - # type: () -> str - """The normalised name of the project the candidate refers to""" - if self._name is None: - self._name = canonicalize_name(self.dist.project_name) - return self._name - - @property - def version(self): - # type: () -> _BaseVersion - if self._version is None: - self._version = self.dist.parsed_version - return self._version - - def _prepare_abstract_distribution(self): - # type: () -> AbstractDistribution - raise NotImplementedError("Override in subclass") - - def _prepare(self): - # type: () -> None - if self._dist is not None: - return - - abstract_dist = self._prepare_abstract_distribution() - self._dist = abstract_dist.get_pkg_resources_distribution() - assert self._dist is not None, "Distribution already installed" - - # TODO: Abort cleanly here, as the resolution has been - # based on the wrong name/version until now, and - # so is wrong. - # TODO: (Longer term) Rather than abort, reject this candidate - # and backtrack. This would need resolvelib support. - # These should be "proper" errors, not just asserts, as they - # can result from user errors like a requirement "foo @ URL" - # when the project at URL has a name of "bar" in its metadata. - assert ( - self._name is None or - self._name == canonicalize_name(self._dist.project_name) - ), "Name mismatch: {!r} vs {!r}".format( - self._name, canonicalize_name(self._dist.project_name), - ) - assert ( - self._version is None or - self._version == self._dist.parsed_version - ), "Version mismatch: {!r} vs {!r}".format( - self._version, self._dist.parsed_version, - ) - - @property - def dist(self): - # type: () -> Distribution - self._prepare() - return self._dist - - def _get_requires_python_specifier(self): - # type: () -> Optional[SpecifierSet] - requires_python = get_requires_python(self.dist) - if requires_python is None: - return None - try: - spec = SpecifierSet(requires_python) - except InvalidSpecifier as e: - logger.warning( - "Package %r has an invalid Requires-Python: %s", self.name, e, - ) - return None - return spec - - def get_dependencies(self): - # type: () -> Sequence[Requirement] - deps = [ - self._factory.make_requirement_from_spec(str(r), self._ireq) - for r in self.dist.requires() - ] - python_dep = self._factory.make_requires_python_requirement( - self._get_requires_python_specifier(), - ) - if python_dep: - deps.append(python_dep) - return deps - - def get_install_requirement(self): - # type: () -> Optional[InstallRequirement] - self._prepare() - return self._ireq - - -class LinkCandidate(_InstallRequirementBackedCandidate): - def __init__( - self, - link, # type: Link - parent, # type: InstallRequirement - factory, # type: Factory - name=None, # type: Optional[str] - version=None, # type: Optional[_BaseVersion] - ): - # type: (...) -> None - super(LinkCandidate, self).__init__( - link=link, - ireq=make_install_req_from_link(link, parent), - factory=factory, - name=name, - version=version, - ) - - def _prepare_abstract_distribution(self): - # type: () -> AbstractDistribution - return self._factory.preparer.prepare_linked_requirement(self._ireq) - - -class EditableCandidate(_InstallRequirementBackedCandidate): - def __init__( - self, - link, # type: Link - parent, # type: InstallRequirement - factory, # type: Factory - name=None, # type: Optional[str] - version=None, # type: Optional[_BaseVersion] - ): - # type: (...) -> None - super(EditableCandidate, self).__init__( - link=link, - ireq=make_install_req_from_editable(link, parent), - factory=factory, - name=name, - version=version, - ) - - def _prepare_abstract_distribution(self): - # type: () -> AbstractDistribution - return self._factory.preparer.prepare_editable_requirement(self._ireq) - - -class AlreadyInstalledCandidate(Candidate): - def __init__( - self, - dist, # type: Distribution - parent, # type: InstallRequirement - factory, # type: Factory - ): - # type: (...) -> None - self.dist = dist - self._ireq = make_install_req_from_dist(dist, parent) - self._factory = factory - - # This is just logging some messages, so we can do it eagerly. - # The returned dist would be exactly the same as self.dist because we - # set satisfied_by in make_install_req_from_dist. - # TODO: Supply reason based on force_reinstall and upgrade_strategy. - skip_reason = "already satisfied" - factory.preparer.prepare_installed_requirement(self._ireq, skip_reason) - - def __repr__(self): - # type: () -> str - return "{class_name}({distribution!r})".format( - class_name=self.__class__.__name__, - distribution=self.dist, - ) - - def __eq__(self, other): - # type: (Any) -> bool - if isinstance(other, self.__class__): - return self.name == other.name and self.version == other.version - return False - - # Needed for Python 2, which does not implement this by default - def __ne__(self, other): - # type: (Any) -> bool - return not self.__eq__(other) - - @property - def name(self): - # type: () -> str - return canonicalize_name(self.dist.project_name) - - @property - def version(self): - # type: () -> _BaseVersion - return self.dist.parsed_version - - def get_dependencies(self): - # type: () -> Sequence[Requirement] - return [ - self._factory.make_requirement_from_spec(str(r), self._ireq) - for r in self.dist.requires() - ] - - def get_install_requirement(self): - # type: () -> Optional[InstallRequirement] - return None - - -class ExtrasCandidate(Candidate): - """A candidate that has 'extras', indicating additional dependencies. - - Requirements can be for a project with dependencies, something like - foo[extra]. The extras don't affect the project/version being installed - directly, but indicate that we need additional dependencies. We model that - by having an artificial ExtrasCandidate that wraps the "base" candidate. - - The ExtrasCandidate differs from the base in the following ways: - - 1. It has a unique name, of the form foo[extra]. This causes the resolver - to treat it as a separate node in the dependency graph. - 2. When we're getting the candidate's dependencies, - a) We specify that we want the extra dependencies as well. - b) We add a dependency on the base candidate (matching the name and - version). See below for why this is needed. - 3. We return None for the underlying InstallRequirement, as the base - candidate will provide it, and we don't want to end up with duplicates. - - The dependency on the base candidate is needed so that the resolver can't - decide that it should recommend foo[extra1] version 1.0 and foo[extra2] - version 2.0. Having those candidates depend on foo=1.0 and foo=2.0 - respectively forces the resolver to recognise that this is a conflict. - """ - def __init__( - self, - base, # type: BaseCandidate - extras, # type: Set[str] - ): - # type: (...) -> None - self.base = base - self.extras = extras - - def __repr__(self): - # type: () -> str - return "{class_name}(base={base!r}, extras={extras!r})".format( - class_name=self.__class__.__name__, - base=self.base, - extras=self.extras, - ) - - def __eq__(self, other): - # type: (Any) -> bool - if isinstance(other, self.__class__): - return self.base == other.base and self.extras == other.extras - return False - - # Needed for Python 2, which does not implement this by default - def __ne__(self, other): - # type: (Any) -> bool - return not self.__eq__(other) - - @property - def name(self): - # type: () -> str - """The normalised name of the project the candidate refers to""" - return format_name(self.base.name, self.extras) - - @property - def version(self): - # type: () -> _BaseVersion - return self.base.version - - def get_dependencies(self): - # type: () -> Sequence[Requirement] - factory = self.base._factory - - # The user may have specified extras that the candidate doesn't - # support. We ignore any unsupported extras here. - valid_extras = self.extras.intersection(self.base.dist.extras) - invalid_extras = self.extras.difference(self.base.dist.extras) - if invalid_extras: - logger.warning( - "Invalid extras specified in %s: %s", - self.name, - ','.join(sorted(invalid_extras)) - ) - - deps = [ - factory.make_requirement_from_spec(str(r), self.base._ireq) - for r in self.base.dist.requires(valid_extras) - ] - # Add a dependency on the exact base. - # (See note 2b in the class docstring) - spec = "{}=={}".format(self.base.name, self.base.version) - deps.append(factory.make_requirement_from_spec(spec, self.base._ireq)) - return deps - - def get_install_requirement(self): - # type: () -> Optional[InstallRequirement] - # We don't return anything here, because we always - # depend on the base candidate, and we'll get the - # install requirement from that. - return None - - -class RequiresPythonCandidate(Candidate): - def __init__(self, py_version_info): - # type: (Optional[Tuple[int, ...]]) -> None - if py_version_info is not None: - version_info = normalize_version_info(py_version_info) - else: - version_info = sys.version_info[:3] - self._version = Version(".".join(str(c) for c in version_info)) - - # We don't need to implement __eq__() and __ne__() since there is always - # only one RequiresPythonCandidate in a resolution, i.e. the host Python. - # The built-in object.__eq__() and object.__ne__() do exactly what we want. - - @property - def name(self): - # type: () -> str - # Avoid conflicting with the PyPI package "Python". - return "" - - @property - def version(self): - # type: () -> _BaseVersion - return self._version - - def get_dependencies(self): - # type: () -> Sequence[Requirement] - return [] - - def get_install_requirement(self): - # type: () -> Optional[InstallRequirement] - return None diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/factory.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/factory.py deleted file mode 100644 index 23686f76..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/factory.py +++ /dev/null @@ -1,201 +0,0 @@ -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import ( - InstallationError, - UnsupportedPythonVersion, -) -from pip._internal.utils.misc import get_installed_distributions -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -from .candidates import ( - AlreadyInstalledCandidate, - EditableCandidate, - ExtrasCandidate, - LinkCandidate, - RequiresPythonCandidate, -) -from .requirements import ( - ExplicitRequirement, - RequiresPythonRequirement, - SpecifierRequirement, -) - -if MYPY_CHECK_RUNNING: - from typing import Dict, Iterator, Optional, Set, Tuple, TypeVar - - from pip._vendor.packaging.specifiers import SpecifierSet - from pip._vendor.packaging.version import _BaseVersion - from pip._vendor.pkg_resources import Distribution - from pip._vendor.resolvelib import ResolutionImpossible - - from pip._internal.index.package_finder import PackageFinder - from pip._internal.models.link import Link - from pip._internal.operations.prepare import RequirementPreparer - from pip._internal.req.req_install import InstallRequirement - from pip._internal.resolution.base import InstallRequirementProvider - - from .base import Candidate, Requirement - from .candidates import BaseCandidate - - C = TypeVar("C") - Cache = Dict[Link, C] - - -class Factory(object): - def __init__( - self, - finder, # type: PackageFinder - preparer, # type: RequirementPreparer - make_install_req, # type: InstallRequirementProvider - force_reinstall, # type: bool - ignore_installed, # type: bool - ignore_requires_python, # type: bool - py_version_info=None, # type: Optional[Tuple[int, ...]] - ): - # type: (...) -> None - self.finder = finder - self.preparer = preparer - self._python_candidate = RequiresPythonCandidate(py_version_info) - self._make_install_req_from_spec = make_install_req - self._force_reinstall = force_reinstall - self._ignore_requires_python = ignore_requires_python - - self._link_candidate_cache = {} # type: Cache[LinkCandidate] - self._editable_candidate_cache = {} # type: Cache[EditableCandidate] - - if not ignore_installed: - self._installed_dists = { - canonicalize_name(dist.project_name): dist - for dist in get_installed_distributions() - } - else: - self._installed_dists = {} - - def _make_candidate_from_dist( - self, - dist, # type: Distribution - extras, # type: Set[str] - parent, # type: InstallRequirement - ): - # type: (...) -> Candidate - base = AlreadyInstalledCandidate(dist, parent, factory=self) - if extras: - return ExtrasCandidate(base, extras) - return base - - def _make_candidate_from_link( - self, - link, # type: Link - extras, # type: Set[str] - parent, # type: InstallRequirement - name=None, # type: Optional[str] - version=None, # type: Optional[_BaseVersion] - ): - # type: (...) -> Candidate - # TODO: Check already installed candidate, and use it if the link and - # editable flag match. - if parent.editable: - if link not in self._editable_candidate_cache: - self._editable_candidate_cache[link] = EditableCandidate( - link, parent, factory=self, name=name, version=version, - ) - base = self._editable_candidate_cache[link] # type: BaseCandidate - else: - if link not in self._link_candidate_cache: - self._link_candidate_cache[link] = LinkCandidate( - link, parent, factory=self, name=name, version=version, - ) - base = self._link_candidate_cache[link] - if extras: - return ExtrasCandidate(base, extras) - return base - - def iter_found_candidates(self, ireq, extras): - # type: (InstallRequirement, Set[str]) -> Iterator[Candidate] - name = canonicalize_name(ireq.req.name) - if not self._force_reinstall: - installed_dist = self._installed_dists.get(name) - else: - installed_dist = None - - found = self.finder.find_best_candidate( - project_name=ireq.req.name, - specifier=ireq.req.specifier, - hashes=ireq.hashes(trust_internet=False), - ) - for ican in found.iter_applicable(): - if (installed_dist is not None and - installed_dist.parsed_version == ican.version): - continue - yield self._make_candidate_from_link( - link=ican.link, - extras=extras, - parent=ireq, - name=name, - version=ican.version, - ) - - # Return installed distribution if it matches the specifier. This is - # done last so the resolver will prefer it over downloading links. - if (installed_dist is not None and - installed_dist.parsed_version in ireq.req.specifier): - yield self._make_candidate_from_dist( - dist=installed_dist, - extras=extras, - parent=ireq, - ) - - def make_requirement_from_install_req(self, ireq): - # type: (InstallRequirement) -> Requirement - if ireq.link: - # TODO: Get name and version from ireq, if possible? - # Specifically, this might be needed in "name @ URL" - # syntax - need to check where that syntax is handled. - cand = self._make_candidate_from_link( - ireq.link, extras=set(), parent=ireq, - ) - return ExplicitRequirement(cand) - return SpecifierRequirement(ireq, factory=self) - - def make_requirement_from_spec(self, specifier, comes_from): - # type: (str, InstallRequirement) -> Requirement - ireq = self._make_install_req_from_spec(specifier, comes_from) - return self.make_requirement_from_install_req(ireq) - - def make_requires_python_requirement(self, specifier): - # type: (Optional[SpecifierSet]) -> Optional[Requirement] - if self._ignore_requires_python or specifier is None: - return None - return RequiresPythonRequirement(specifier, self._python_candidate) - - def should_reinstall(self, candidate): - # type: (Candidate) -> bool - # TODO: Are there more cases this needs to return True? Editable? - return candidate.name in self._installed_dists - - def _report_requires_python_error( - self, - requirement, # type: RequiresPythonRequirement - parent, # type: Candidate - ): - # type: (...) -> UnsupportedPythonVersion - template = ( - "Package {package!r} requires a different Python: " - "{version} not in {specifier!r}" - ) - message = template.format( - package=parent.name, - version=self._python_candidate.version, - specifier=str(requirement.specifier), - ) - return UnsupportedPythonVersion(message) - - def get_installation_error(self, e): - # type: (ResolutionImpossible) -> Optional[InstallationError] - for cause in e.causes: - if isinstance(cause.requirement, RequiresPythonRequirement): - return self._report_requires_python_error( - cause.requirement, - cause.parent, - ) - return None diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/provider.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/provider.py deleted file mode 100644 index 5c3d210a..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/provider.py +++ /dev/null @@ -1,54 +0,0 @@ -from pip._vendor.resolvelib.providers import AbstractProvider - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional, Sequence, Tuple, Union - - from pip._internal.req.req_install import InstallRequirement - - from .base import Requirement, Candidate - from .factory import Factory - - -class PipProvider(AbstractProvider): - def __init__( - self, - factory, # type: Factory - ignore_dependencies, # type: bool - ): - # type: (...) -> None - self._factory = factory - self._ignore_dependencies = ignore_dependencies - - def get_install_requirement(self, c): - # type: (Candidate) -> Optional[InstallRequirement] - return c.get_install_requirement() - - def identify(self, dependency): - # type: (Union[Requirement, Candidate]) -> str - return dependency.name - - def get_preference( - self, - resolution, # type: Optional[Candidate] - candidates, # type: Sequence[Candidate] - information # type: Sequence[Tuple[Requirement, Candidate]] - ): - # type: (...) -> Any - # Use the "usual" value for now - return len(candidates) - - def find_matches(self, requirement): - # type: (Requirement) -> Sequence[Candidate] - return requirement.find_matches() - - def is_satisfied_by(self, requirement, candidate): - # type: (Requirement, Candidate) -> bool - return requirement.is_satisfied_by(candidate) - - def get_dependencies(self, candidate): - # type: (Candidate) -> Sequence[Requirement] - if self._ignore_dependencies: - return [] - return candidate.get_dependencies() diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/requirements.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/requirements.py deleted file mode 100644 index d2e4479b..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/requirements.py +++ /dev/null @@ -1,119 +0,0 @@ -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -from .base import Requirement, format_name - -if MYPY_CHECK_RUNNING: - from typing import Sequence - - from pip._vendor.packaging.specifiers import SpecifierSet - - from pip._internal.req.req_install import InstallRequirement - - from .base import Candidate - from .factory import Factory - - -class ExplicitRequirement(Requirement): - def __init__(self, candidate): - # type: (Candidate) -> None - self.candidate = candidate - - def __repr__(self): - # type: () -> str - return "{class_name}({candidate!r})".format( - class_name=self.__class__.__name__, - candidate=self.candidate, - ) - - @property - def name(self): - # type: () -> str - # No need to canonicalise - the candidate did this - return self.candidate.name - - def find_matches(self): - # type: () -> Sequence[Candidate] - return [self.candidate] - - def is_satisfied_by(self, candidate): - # type: (Candidate) -> bool - return candidate == self.candidate - - -class SpecifierRequirement(Requirement): - def __init__(self, ireq, factory): - # type: (InstallRequirement, Factory) -> None - assert ireq.link is None, "This is a link, not a specifier" - self._ireq = ireq - self._factory = factory - self.extras = ireq.req.extras - - def __str__(self): - # type: () -> str - return str(self._ireq.req) - - def __repr__(self): - # type: () -> str - return "{class_name}({requirement!r})".format( - class_name=self.__class__.__name__, - requirement=str(self._ireq.req), - ) - - @property - def name(self): - # type: () -> str - canonical_name = canonicalize_name(self._ireq.req.name) - return format_name(canonical_name, self.extras) - - def find_matches(self): - # type: () -> Sequence[Candidate] - it = self._factory.iter_found_candidates(self._ireq, self.extras) - return list(it) - - def is_satisfied_by(self, candidate): - # type: (Candidate) -> bool - assert candidate.name == self.name, \ - "Internal issue: Candidate is not for this requirement " \ - " {} vs {}".format(candidate.name, self.name) - # We can safely always allow prereleases here since PackageFinder - # already implements the prerelease logic, and would have filtered out - # prerelease candidates if the user does not expect them. - spec = self._ireq.req.specifier - return spec.contains(candidate.version, prereleases=True) - - -class RequiresPythonRequirement(Requirement): - """A requirement representing Requires-Python metadata. - """ - def __init__(self, specifier, match): - # type: (SpecifierSet, Candidate) -> None - self.specifier = specifier - self._candidate = match - - def __repr__(self): - # type: () -> str - return "{class_name}({specifier!r})".format( - class_name=self.__class__.__name__, - specifier=str(self.specifier), - ) - - @property - def name(self): - # type: () -> str - return self._candidate.name - - def find_matches(self): - # type: () -> Sequence[Candidate] - if self._candidate.version in self.specifier: - return [self._candidate] - return [] - - def is_satisfied_by(self, candidate): - # type: (Candidate) -> bool - assert candidate.name == self._candidate.name, "Not Python candidate" - # We can safely always allow prereleases here since PackageFinder - # already implements the prerelease logic, and would have filtered out - # prerelease candidates if the user does not expect them. - return self.specifier.contains(candidate.version, prereleases=True) diff --git a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py b/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py deleted file mode 100644 index cba5a496..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py +++ /dev/null @@ -1,174 +0,0 @@ -import functools -import logging - -from pip._vendor import six -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.resolvelib import BaseReporter, ResolutionImpossible -from pip._vendor.resolvelib import Resolver as RLResolver - -from pip._internal.exceptions import InstallationError -from pip._internal.req.req_set import RequirementSet -from pip._internal.resolution.base import BaseResolver -from pip._internal.resolution.resolvelib.provider import PipProvider -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -from .factory import Factory - -if MYPY_CHECK_RUNNING: - from typing import Dict, List, Optional, Tuple - - from pip._vendor.resolvelib.resolvers import Result - - from pip._internal.cache import WheelCache - from pip._internal.index.package_finder import PackageFinder - from pip._internal.operations.prepare import RequirementPreparer - from pip._internal.req.req_install import InstallRequirement - from pip._internal.resolution.base import InstallRequirementProvider - - -logger = logging.getLogger(__name__) - - -class Resolver(BaseResolver): - def __init__( - self, - preparer, # type: RequirementPreparer - finder, # type: PackageFinder - wheel_cache, # type: Optional[WheelCache] - make_install_req, # type: InstallRequirementProvider - use_user_site, # type: bool - ignore_dependencies, # type: bool - ignore_installed, # type: bool - ignore_requires_python, # type: bool - force_reinstall, # type: bool - upgrade_strategy, # type: str - py_version_info=None, # type: Optional[Tuple[int, ...]] - ): - super(Resolver, self).__init__() - self.factory = Factory( - finder=finder, - preparer=preparer, - make_install_req=make_install_req, - force_reinstall=force_reinstall, - ignore_installed=ignore_installed, - ignore_requires_python=ignore_requires_python, - py_version_info=py_version_info, - ) - self.ignore_dependencies = ignore_dependencies - self._result = None # type: Optional[Result] - - def resolve(self, root_reqs, check_supported_wheels): - # type: (List[InstallRequirement], bool) -> RequirementSet - - # FIXME: Implement constraints. - if any(r.constraint for r in root_reqs): - raise InstallationError("Constraints are not yet supported.") - - provider = PipProvider( - factory=self.factory, - ignore_dependencies=self.ignore_dependencies, - ) - reporter = BaseReporter() - resolver = RLResolver(provider, reporter) - - requirements = [ - self.factory.make_requirement_from_install_req(r) - for r in root_reqs - ] - - try: - self._result = resolver.resolve(requirements) - - except ResolutionImpossible as e: - error = self.factory.get_installation_error(e) - if not error: - # TODO: This needs fixing, we need to look at the - # factory.get_installation_error infrastructure, as that - # doesn't really allow for the logger.critical calls I'm - # using here. - for req, parent in e.causes: - logger.critical( - "Could not find a version that satisfies " + - "the requirement " + - str(req) + - ("" if parent is None else " (from {})".format( - parent.name - )) - ) - raise InstallationError( - "No matching distribution found for " + - ", ".join([r.name for r, _ in e.causes]) - ) - raise - six.raise_from(error, e) - - req_set = RequirementSet(check_supported_wheels=check_supported_wheels) - for candidate in self._result.mapping.values(): - ireq = provider.get_install_requirement(candidate) - if ireq is None: - continue - ireq.should_reinstall = self.factory.should_reinstall(candidate) - req_set.add_named_requirement(ireq) - - return req_set - - def get_installation_order(self, req_set): - # type: (RequirementSet) -> List[InstallRequirement] - """Create a list that orders given requirements for installation. - - The returned list should contain all requirements in ``req_set``, - so the caller can loop through it and have a requirement installed - before the requiring thing. - - The current implementation walks the resolved dependency graph, and - make sure every node has a greater "weight" than all its parents. - """ - assert self._result is not None, "must call resolve() first" - weights = {} # type: Dict[Optional[str], int] - - graph = self._result.graph - key_count = len(self._result.mapping) + 1 # Packages plus sentinal. - while len(weights) < key_count: - progressed = False - for key in graph: - if key in weights: - continue - parents = list(graph.iter_parents(key)) - if not all(p in weights for p in parents): - continue - if parents: - weight = max(weights[p] for p in parents) + 1 - else: - weight = 0 - weights[key] = weight - progressed = True - - # FIXME: This check will fail if there are unbreakable cycles. - # Implement something to forcifully break them up to continue. - if not progressed: - raise InstallationError( - "Could not determine installation order due to cicular " - "dependency." - ) - - sorted_items = sorted( - req_set.requirements.items(), - key=functools.partial(_req_set_item_sorter, weights=weights), - reverse=True, - ) - return [ireq for _, ireq in sorted_items] - - -def _req_set_item_sorter( - item, # type: Tuple[str, InstallRequirement] - weights, # type: Dict[Optional[str], int] -): - # type: (...) -> Tuple[int, str] - """Key function used to sort install requirements for installation. - - Based on the "weight" mapping calculated in ``get_installation_order()``. - The canonical package name is returned as the second member as a tie- - breaker to ensure the result is predictable, which is useful in tests. - """ - name = canonicalize_name(item[0]) - return weights[name], name diff --git a/env/lib/python3.8/site-packages/pip/_internal/self_outdated_check.py b/env/lib/python3.8/site-packages/pip/_internal/self_outdated_check.py deleted file mode 100644 index 8fc3c594..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/self_outdated_check.py +++ /dev/null @@ -1,242 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import datetime -import hashlib -import json -import logging -import os.path -import sys - -from pip._vendor import pkg_resources -from pip._vendor.packaging import version as packaging_version -from pip._vendor.six import ensure_binary - -from pip._internal.index.collector import LinkCollector -from pip._internal.index.package_finder import PackageFinder -from pip._internal.models.search_scope import SearchScope -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.utils.filesystem import ( - adjacent_tmp_file, - check_path_owner, - replace, -) -from pip._internal.utils.misc import ( - ensure_dir, - get_installed_version, - redact_auth_from_url, -) -from pip._internal.utils.packaging import get_installer -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - import optparse - from optparse import Values - from typing import Any, Dict, Text, Union - - from pip._internal.network.session import PipSession - - -SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" - - -logger = logging.getLogger(__name__) - - -def make_link_collector( - session, # type: PipSession - options, # type: Values - suppress_no_index=False, # type: bool -): - # type: (...) -> LinkCollector - """ - :param session: The Session to use to make requests. - :param suppress_no_index: Whether to ignore the --no-index option - when constructing the SearchScope object. - """ - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index and not suppress_no_index: - logger.debug( - 'Ignoring indexes: %s', - ','.join(redact_auth_from_url(url) for url in index_urls), - ) - index_urls = [] - - # Make sure find_links is a list before passing to create(). - find_links = options.find_links or [] - - search_scope = SearchScope.create( - find_links=find_links, index_urls=index_urls, - ) - - link_collector = LinkCollector(session=session, search_scope=search_scope) - - return link_collector - - -def _get_statefile_name(key): - # type: (Union[str, Text]) -> str - key_bytes = ensure_binary(key) - name = hashlib.sha224(key_bytes).hexdigest() - return name - - -class SelfCheckState(object): - def __init__(self, cache_dir): - # type: (str) -> None - self.state = {} # type: Dict[str, Any] - self.statefile_path = None - - # Try to load the existing state - if cache_dir: - self.statefile_path = os.path.join( - cache_dir, "selfcheck", _get_statefile_name(self.key) - ) - try: - with open(self.statefile_path) as statefile: - self.state = json.load(statefile) - except (IOError, ValueError, KeyError): - # Explicitly suppressing exceptions, since we don't want to - # error out if the cache file is invalid. - pass - - @property - def key(self): - return sys.prefix - - def save(self, pypi_version, current_time): - # type: (str, datetime.datetime) -> None - # If we do not have a path to cache in, don't bother saving. - if not self.statefile_path: - return - - # Check to make sure that we own the directory - if not check_path_owner(os.path.dirname(self.statefile_path)): - return - - # Now that we've ensured the directory is owned by this user, we'll go - # ahead and make sure that all our directories are created. - ensure_dir(os.path.dirname(self.statefile_path)) - - state = { - # Include the key so it's easy to tell which pip wrote the - # file. - "key": self.key, - "last_check": current_time.strftime(SELFCHECK_DATE_FMT), - "pypi_version": pypi_version, - } - - text = json.dumps(state, sort_keys=True, separators=(",", ":")) - - with adjacent_tmp_file(self.statefile_path) as f: - f.write(ensure_binary(text)) - - try: - # Since we have a prefix-specific state file, we can just - # overwrite whatever is there, no need to check. - replace(f.name, self.statefile_path) - except OSError: - # Best effort. - pass - - -def was_installed_by_pip(pkg): - # type: (str) -> bool - """Checks whether pkg was installed by pip - - This is used not to display the upgrade message when pip is in fact - installed by system package manager, such as dnf on Fedora. - """ - try: - dist = pkg_resources.get_distribution(pkg) - return "pip" == get_installer(dist) - except pkg_resources.DistributionNotFound: - return False - - -def pip_self_version_check(session, options): - # type: (PipSession, optparse.Values) -> None - """Check for an update for pip. - - Limit the frequency of checks to once per week. State is stored either in - the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix - of the pip script path. - """ - installed_version = get_installed_version("pip") - if not installed_version: - return - - pip_version = packaging_version.parse(installed_version) - pypi_version = None - - try: - state = SelfCheckState(cache_dir=options.cache_dir) - - current_time = datetime.datetime.utcnow() - # Determine if we need to refresh the state - if "last_check" in state.state and "pypi_version" in state.state: - last_check = datetime.datetime.strptime( - state.state["last_check"], - SELFCHECK_DATE_FMT - ) - if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: - pypi_version = state.state["pypi_version"] - - # Refresh the version if we need to or just see if we need to warn - if pypi_version is None: - # Lets use PackageFinder to see what the latest pip version is - link_collector = make_link_collector( - session, - options=options, - suppress_no_index=True, - ) - - # Pass allow_yanked=False so we don't suggest upgrading to a - # yanked version. - selection_prefs = SelectionPreferences( - allow_yanked=False, - allow_all_prereleases=False, # Explicitly set to False - ) - - finder = PackageFinder.create( - link_collector=link_collector, - selection_prefs=selection_prefs, - ) - best_candidate = finder.find_best_candidate("pip").best_candidate - if best_candidate is None: - return - pypi_version = str(best_candidate.version) - - # save that we've performed a check - state.save(pypi_version, current_time) - - remote_version = packaging_version.parse(pypi_version) - - local_version_is_older = ( - pip_version < remote_version and - pip_version.base_version != remote_version.base_version and - was_installed_by_pip('pip') - ) - - # Determine if our pypi_version is older - if not local_version_is_older: - return - - # We cannot tell how the current pip is available in the current - # command context, so be pragmatic here and suggest the command - # that's always available. This does not accommodate spaces in - # `sys.executable`. - pip_cmd = "{} -m pip".format(sys.executable) - logger.warning( - "You are using pip version %s; however, version %s is " - "available.\nYou should consider upgrading via the " - "'%s install --upgrade pip' command.", - pip_version, pypi_version, pip_cmd - ) - except Exception: - logger.debug( - "There was an error checking the latest version of pip", - exc_info=True, - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 458cc6ce481af69adc60127e85797c387fb8dc83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmWIL<>g`kf{3<5@gVv!h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6v3za+OnzaX-5k6v!-zkJl@x Vyv1RYo1apelWGSt`7;nR008oqC2#-$ diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc deleted file mode 100644 index 7d44b073da474c69bbdf2017f8f66194958dc053..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1345 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc deleted file mode 100644 index cd031bd735a7a5489284560c70b13047e46c01cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3599 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc deleted file mode 100644 index a32955aabc843d98c9302f07aed4163547f6e663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2676 zcmZWrTW{RP6`movTrT$_X)RykxGmct0XB(OK@uQskOUSaxpiW%3)@O;A^=S-M_S6f zY-eWWYDM;;4vN0`rN3ae=tG;I(1)VP&zRRf(=wCOh~nXUq-mbB8g-=^d%l3lR~>pXG!h!T9+ir;=jGUFj(4gM#PwUgC! z&0o`2>Pa`f;9t;VCs|J~`WHci%r3FZbLwA-8j<@A@n4HpqgK@ZhWb~dPP77)*CTqL z^wz$I{gXk@R#&!f-P_rE5bWN&9o*S@u(`eYU^5tO-q}&jO+FmON9+x_2J^`cbg;tDUVcf_uAz!L7kBfodKN z1#~N)-@iN9X2U#U+5(WAyJIvMCNQ>c$JrC;TidaaJl>liXK3Ko7mo$K4c``g;yY*x zG9z>FT|pyynUux>DNRWWa%f2NnZZ9RjL4W-I6tgGYwJ;cZhi!^*@K0o1CmK$ARp;k z1|m?HGq)PgDJ9uk3+d)FLlm<0d%enGoBvUdm$f_muc#ZDpxwDlP`fbsKVUCbRGY07 z<{b8_S27?r_Vm52JUe1sdZBmbYft7d9mivjv)@c00x8R+hi=IZ`cu=p;Z2>B@|~0N z#z{GCi^*Q3qm=XGPhZeCUeLFCtI9d50>+dZi#QW9%!W)^F+_^j!FkGtK^jWlz==75 zU^j+&n#MASBW@zm8iit{>~K70S;W!xsY<5NDEc0L})$BoQ0us{|vKj2RdG@v(Yyi5!Yx%*G#n_+GFea<(3%qfqXRTswx8kZ3tmJ@q;|?i(cpiHOn_hm=Bsm~bQbb! zg%erN5z=Qm0L|KetJ^&D8B@= zURT+%2;lZt7`t@9WUz-Z&7uIn7l`2qkge>h=T|^St)md21s4fI5DX`Bq}Gx0G?t@$ zB7;-Rs20keZiZue(8%ULLPHmq@p!JY0y|>Ag%kr<387HIx`9X!5TE=4n!)YsJJ55L zl|W)ruE-~R$WTRHLP`LJ;w;eM42B^bMK$55rw6P&^9JsO2HJy_(Rb0Zch>wA1=g2v zy3g}8K>Hs9M{Gkw3>zTn814^_W!Vn3YYsrs(65EAcz3a)asXx>R}NkV6hV@ZJ<202jKC;p;V33l#5e5=Z8>=H8gvMvhcKuvj0WU z1*8Xf9nMdlz$(InhSXgEg8_M~0*&#qQ`5jf>VGVoe*!W+V{o%~P1SJ+xbjaR&GygI zY(IsaCZd0Cy*jK3n$^YA2g4Fk6_=~8s_QJ>m&ao;&GElVt-UI6mLx26TIHeUt#q7o zS^aLf@c%KXejJp&Fw{gtuf1w$u~EE1yajx};vYfI$$5VnV1l<%zX4vmUAf%}w4Z~3 ze*_$zzd9r_x=9@ D9?akH diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc deleted file mode 100644 index b49799fd71159768bbc3dae5ac7f6148ed2486f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139 zcmZ`(OK%e~5VrS`Y|?E>+NcK(XirFyNOC|zAhn39FP>2as%TfB)n@G`+wQBjmo`zt z1;ma207w1?Kf_l}+&OV#ylozbV#~Akd}Gfyp79dvFVx^QIkCc%!o>H*)7MGYXNSO5-AglR7jO95t}TN z6>^Kz`nFr4I<0)dZk5!@>SyFGk+nCd+4v3KP!r4gPRKtT_c)8h?2vp`E zjp=5Wm6a!bv>YZ}_)*mA`TQm|@r6IPu1&26)F+hjIbu(dDD2I(Gy5#^#ea~T(VGz- zurLz~KFZTTrsPeQrefwz8ab!zDzX5po4jt2U{ryz4TC=i5uynmqaE~qW1@}L1v7^!}Y&aERf#^3a@acX>rLO8d^7*eK_^hADG!gus!>Gtv5+;4ePn@)ON(14DfiIka&tXEV4z$=8!C-M;yISbClA)6) zXGwaI%+G`wb;5p0ara{!QlxL7mDlHET1L1j1 zlc{@=B}RE338}+D5_{4tIQ>9u70|zX9T8`pEX-PYlKH_IC9R7ArBUlq-W%TU4I_nh zyf6`zC4ST?>b5hdqS&>wp=@O8q82zR;0}1;H4vz5U<+$_9j_QAZ3VLi=(xh{S+vIIv)SfYF7mV6sm_aI-p$tmb3soAdq%@WX&niq4&eWfw o@Lq(!Al3@IjW{KFL?5dP<99*W*w$>#z%@ey{x|eLM%~i?0ThZb^Z)<= diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc deleted file mode 100644 index fbf5aac2ed0c684750dd60df0163a60dcd63a221..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1247 zcmZuv&u<$=6rR~%Uay@J(zJq7q?NeDw6@h)stN*B)ph`px>b`%beqUp?~LOm6^T;>UqMfFrWG@o(^F%#~BloZtd)b`#47X0`8o-+Qy~ee-sXHa0v2>+7HX81C2z z{i(_Na)CUBSNsBoAc7eRO2h#!xDglynt=&uFl%ZDHb&IuJ>VvDrj?*Fbpv-=4XO}F z-+06t8-O)p7g#4wfg7Y!;4R`7_!g-axJkURaasx9rp986)Rs87P3mOh2NY}*e1ICa zu0R_aG_cxw{`%$XVfTxE_p9Nnqru?I!RHNAS^Ke&%0A39MwN9)zmpesF2~I$7mkKU zk1whvHb->jGFoOkyJe`eyUK#gsJII~qm;zS>6?!~JvkO1?!0LppSMmPG$O3^TrUd{ z28+7zir>IU)I%o^kBv)wY0S|A&+!s-YmTHb$KPXue>C1j3v+HPv4Jo;K;J@cVG-a2 z6H{m5``)EFH;F}T&53hn@Se06&fJ7rD{oO*B4X)kq_Ql#t=H{AT~oS?Dsh)M`&D|2 z+7d1GK&ux&cPBJD^Fx0$lT`RZayX|yPC100y?E}+)Q?imX(ZXqCscyt%L(;qQjWy) zd{}!SW1|r2z;>2KA)~ERDl<;U6uu=ln|ENJpbekJXVgzKn(Q?EH1S`~}y-(PL(?5+}> z-Sut2_WQi1i&vs_n#GLrP2ErHFQ&F;?iU(9nWiLX^fN6>_+VUIJVxEH@V0r)%GlqQ H=b8TjK>kvX diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc deleted file mode 100644 index 4e8d687d67a33216ed97ade444ea7680911aedca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1299 zcmZ8h&yV9Y6i(7ir<559p%n+j;oVl1I>`a{Fe`+1w?Yg8%4nGtY%i4?I}Q>vDnyE7$M*NW_rA}5ad|mU@cHV;U$@`oN%9*FPM--5 zp5PmvVZ#%is$@goOr<*8WGVG0YNGQ^o+cvq@8LLCXL`Ds>hsMx&Y$x$KK&ux%y{}m zvY7pjILUgE_PJ)#;P=hXUf#aku5LbDeX@Q2V!i%&{m~-pXP>($tzoLqKb0X?DQ!DG z)F)mme8U55V)82eDdXwSX_~~zx5@VuDPw=&!j&-5GX)3FoD&{u>wzf+R&k)I&RJ<< zDCTp(=LSPrFDqQpfs+mz7VzZ|#9k20$rj+EmPYUbo{5UJL4d76hR}*IU@vjp9$D4h~;+r`G3u!PtM=>fT5oQhJ%f6Q>uHpBrB(Q%DNI(vd; z13zg(M6!Y}0U7uJp{;97ljwF3r4|Ts!W!;H9O-GhNA6?Vca~}*_L4<`L1X}j+Klm? zw|mJE2DGReW@OMq5f988;xUFrrUOYXy+HQ(f8ZJs*Z@}ETjvLKr&uKhfJP{{go6NM z564=L%G6`Jt^dDBfMOhV36G1mPZl>N)6&&f!S$07yT3F0Kp-hM4O z>^h=F76_G>F8+gBz#S!jkZ6#aNrf9Q@4Ahx7l0KFC=02K&M4-$N-z{X2mwuuE<7&F zdl{Q{S5#J)u5+x!b>--Y^3kK~>(P9CFR=m$RLgIUg@V>_;Z-+qBnK69l4NfsKg!|l zPNDXlZJ|QyVMB{pQ|!zM`>KO#<2=(cXeolP*>OOu6uXasUgMf;95MZWgDdm z<;fu_T-VRGN6`o}%&Fj-Nd8@<+bd?0+HOns2i!4vynEVa5i;Woo diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc deleted file mode 100644 index 85a15693aec547c3c173dd09b2b29e5272bcbc6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5603 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 v{s^PM4)`kUMztTI4mRc@a6f+zEcZ~Nh7 z8V6qDPeZHv0h5raWb5a*m$$UtaoT6Jf91Me_Y_oZm_~w2)p~jmCYFYkc(FB>JD?KPcovgiEDxg$z9Kr5~B4g?C>(_(3mr&6P~2luhp_&9)*xvZx;>JPti! zrHLaHtD_(&sKF{t#67_}|`FB3s<8!`q4%%%W!Sm{u-`O86g#I*x z>kom!78LmgsstrCLpdH`Z2BZ41JbnCz=GDw?A#eR7;#5Dg0Y>sxi|1~I-n5mB<{~> zu#|WSh1O4&5+B;-WI1U;+e%0ub=rTyDX4?>ooFb_tX7<*c~uG(!rbalhtCdK?}zQ) zk8J-S40pn(9ir)8rP8v9GVMICtBl8HhwBf9K@Wmh|MP~|Ipf#5WJ{&1hGS`;!k z%FE-+T90 zHLke)4G9WA(^P*y-c)(DS*6uRT~twg%9D+=W6raUhxKs$U^vdqw@sE7iVL{rX06gp zZZ^AjtFgZOu5<2~`x@$yB@DkeKr!=XvH|4@bQC(l2|gua#gK5mrpTq0SXcPczCy3b z6ix9WVi{+(G0a) zSj_<~Wp@r*S375E@!;!Ff6(i*r{MwH-TAJ^UTp98clN>#)s`GfO{*+Yqf+FWlu~;O zz#Um-snRRoDqwF2sk1FaDYUoOpLP5fQC80;fjrE#H)rlYF2oX`AzY|Fgd$g-2l^u5W{5y=3D5Tw-OA>KvM*utpR8l;QI6yTxd_RC^;U!U^j1ifvpLv1|z67Z5FYKigoE@j}F>E-B>P(rvd0wgU zBD&cuErK|bv$L|YJguu>6oK%&&DRhz7>Uo|_qEgLzk?f{gG;t=_`xmYG+l7^64pwS zxX5!c#WoS2L%-A3K4YUAOp!At3{b*&iD*NmKL#V}{%b_t#)!H=GPt6!On^Hd7*Pnv vRK{l-(KJjnXI%TG#srP#G<}qpNuBX;%u;D`sReSQq(yA}o<&`{O27IC_@cec diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc deleted file mode 100644 index 033d67bbc1c0ae8931aa37a28e2e801a3d37785c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4158 zcmbVPTW=f36`t7}mlR1|EGxdH*Z^%^7BQ8?ahe#0YR6V>r45}(wqq~qtXDfja?QO^ zv&%?gsTWIVo{9qb0fmIV)c>OBFUa$}_NjlNFYP(ABz1{{0$pNeXLinV(LaB$A)XfrfbHQYpF3K zD#f;I$7Q!1SKNyFW=1n{)vc2DVmMv+_`w(osSpXh4`F%E?#sO zm8=c=&%5VA_PqEGWXq8jFS$#UBvt5Dp!XK`*o=FD&9Ew~b#(XQeZuN&_JFWieraEK zFGGKh%|m~lUxxk_rfrbM!oOfwq(SAZznP`cAm?5f_fwI#8oDfpITujkOxoD&@!d>T zu=R}}4R{73)dzmo{XEQKKM%TcX57odq$B6ok}UV5$j`$xSrsA`u*{6$KJ$X^An9e$ zUHJUj7tg%A4_5E~)?0tvYOS^IH%w{V3xix5zYDWm+MkArFLu`+O1qV=^L!u@X|I6^ zey$YiUp%`GicAleR*fz+q?L934{m&<-q%0=P`z)w|3QGeJ^AR+xeX=z8Y)g)$_Sh& zb#->0>C8BwuE9-aGV6fsQ`cf8W*-o@#LBD!ZyUW0?=q{gI=m}vmd(L?hRw4Dcvsmu zwg~T<^7WFm&`6#Q{X5RK@cVr(oV@Gj&gLMDSmwloC=dG)cW?_lb6_M*0`B+;bAm1p zdKrlG*zr4l2)?a2@br>&JGs_LQ|1(hQc<5F(koV4xuQ6~jdbYmy+W3aNHhDi1p_bs1F1@~sX}_)cG}e25y+CIgOg`17&# z#WXKS2T9(%6{Ue6Wh>3;B)Fk^Hi*SrsLLt<@|p_V(b<)%Csn5z!f$wT0vApQpf9k{Y-okm zdWYu?U70M)c%~l0PF4U-USaatoy>-rrv%5UJ_3`9&6I{q3>k=r9p>8tOVBlEC4GL9(V#jx?O77)Bqyx{EyFC_X?RAd3`i0aOAVWSZP*i!^qS$Nf!U8@SU2 zAwz3=F`1wH&4Nqt?ymb`#vOFtgzTNL?IfVnQPh7zba?)8qF70Bha!oa&L8$#jhaCC z7N=T5IvVLl_wZaRE&`2N4x!^DQpmzRy!52gg}HzYtRS7xIoAO8u(6u0BLyw z4Q!MOoLI$vq|r(9Ok71_Q+<*Kt}Au;eik*0iebI6x5gpr*Dy8v2~@;3Xq{?w0e%{_ z|5G(=TBUVu4*E77UPjOGtobG#r?55Q2ZgOU&|BaN*g<;*v1fybx8WmT--4HN)oZP| zuGjGc(qT~{I|#g{&!80O)`qpQ8HG1~u<(@8>M#eOLvpyH`}7ETj1K)DhmP;G!-!vt z!XBVy^Cb`R{|gzgtzV(pWvHNyEF=xod}d#A;j|x7v%6}*q{r;yoUENn?lY+^`C`#cdhVg7`MjJ}_D z#V7FPe;AH(Z4gtuO|&W!wWwba$Z*o~&EAZ}B`sMs2<7!#b7_=P#5uw>}u z9Jz<=YcI82?~o9#<)4m&*gN;qGaJBZ zi~Gk&-t8RLbp|Mmnvv5a6-6DpYFfK2s@k!R*oZ=!Yf|uI63gKr2ReIh8;07uZ$V;d7 z6vO#$AD|_W`=mAQ%%EvitZGYo4pTr#`&L0QD@ed9@K-fkThtcKDy?b;y`onsBm!F1G|Y-V_vL>9ja>O@ diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc deleted file mode 100644 index 95679c22793c68d290a2762038fea1c7e77fafe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 932 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc deleted file mode 100644 index cf6bcf15d3cf2c9ce3852805f4b44641fe641c99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2608 zcmaJ@&2HO95ayDUM9EV88^=!4b{n8U1jKUN^ircJVmMA}BvuUD0TLDgMT;w$Hvh7_ zN@_y}+Pdhe57480>?`!x$Jicw>MQip&MYNCc7Rgg{tkz;GvD`7FKV@l0oTi)|M32t zGK{})GI?1rc?h@o9h$%hNMyvsB?QN2WV$BwR%FGtYwI;TD#S&%sKbD?rc2g&guP1G#@Xx3wk^iU5^*t zMX)soH`vkzahHQ?Q2WVnZwA+bY3OeSGr=tMw}ZK09{LXgbI+(R{0;FNb)u&I1Cd5O z$-FSmQZAdYR(Z@=u;X*VILvCKz%9OjrVkZ4c6b%fD2)N>8yDovl;*$+ ztbr{Hve+l*<^_ROt8ewq<09n3_J1XYQK4{c9J2N?4LejGGTIH_vV`uO$ip<9zE)XNhe*S>-52j#6!}wL&HQ0%2@_p zSR%uu3x0EN+5v_X`$s8XiNi#(KO8r=qMi4)NnhN<86?b?Iat@O8eBf(nZ*ZHt1 z=vMO9kHTPYgqStD)uFASOW|cYxh;C=Lq-!whqk7jltZ5Lw>9?_Y1B)+0OeKHv7eUyfYvSL3|7NDhWtLZCmQPs)hsO2l$-ne?|S{{}+wExZEOYo+D)>mbm zt!81i(n~VGeawQDcZZBcD_`~wP97YbM7XyKsh5lcmRA9pWGCvnE*P*W zN6zs4i{M>o-KjaIO)BOh;WuHe4X_+vh;__?#`^a#2*??cfOtuc%yX09?HdED56IRd z8%Jkm@+qzcfO!5eFwcMwgVD~SEDVZ)B};wd$T=q$Cg_QMX7!;4n(^Cdej=37 ztk+Z}6k#HypR^grq^bqfmn|UYq|T`7WO%AN8Hy@KX}8O`D!uc00;S~+`f;MP4a`Xs zj+(?RT(dhMrK-@5Qo#U|HfBQAM!|WBA2a2QrfLeUK`K#sHRkeW8QoE6?!zrUgvKb^ zq)MEBO|wcW1jgnZu}ue{Q?x2X+g<_>#)7v7&s`WGaLxfheKH_{h6)tkJTCJ)5+DFO z&_ao=Q%{#=H|IF2;`_2U3Lj}peL7j}`xKV2TG|WfYLZGiRJ*)@r_;NaWwcqhbo|PK zl=FFr6&5h${6mBy>IGq2@&#DCk|Z^cWxB$yCt#PetB475EXU-S$V&;rugW+T|2fb+!V8WXP{Y|x+s=U?Q+h2e7Y;%|21}6~tN6@Lc zN%VM8m@uIVNQtZt#6=4m7q6bChL35iMiJvL!7e|CSs~Ym12_K+U-F@e^6c#H?ELx7%pR_+bO?-Bzy8MmunGAc z7u5lKyXiH_*P?1-LNfw?VK#Tv{V(Fecp6+N{6Lgs-8@?f^TSF-ymdlLz% z-25!aT_ppd-DD}|o$tmA`g|c`_c3qw&@x9S7ls6k9)>Nf~c_H94MsaXgLj zY{;V&AWVaJILV_}562g$TuGfxR4DaeJS`j!B2muy3OZxFWU~j=_y?uL|Hp7nE}92K zwLz7_xUQM%!Bp63kVxb9f~?_Y?<~+aao&TS()vctdR40CfdyC4h(U1#%&ec2IXS0u zx-T`F?a_Uyr)-mnG2686jL7|L8Skk ziuJ1cMW22GVr4=;ttI5P>@9~VTs97&X9C;+Fuz$Cz03S+S=&6)B2tekrXSW!*X91( z>?!1MQHhAkoniNH^u_SHfaT9BmOsAR@=`LyS||td^^j|}mz7X-b*Q3o&aoMaHc}0Z zd#f@!YLfDW=;xrgOu~mXfBumfd0lK`RL6PI;XKL2Bu2i+`Rhp#FHc&Wi!9_^^+Bon z0EwxG4dgbFJVb(duat+u4%<~ZK(O63-gl_Y92>s2p|&|4c|Csv9-RSyBU6#7LG7_I zCFrkJ&vo>p>8WDV?3Pc}z&urhd^(QOQ-vi|G?$A8EL0Oo%WP-I=Q7NV^}C!doF@x3 SzQ**J4(rh#>oJ?&xBdq5&!LF` diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc deleted file mode 100644 index 5b0aab04f83e19285136e278ce2f923aa964e0b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2921 zcmZ`*-EQ1O6t=xyud{z?(*lJSa4C=&#hVI{5Dlq-s(+$QQIkqE6j@%+?8ek)$L`}} zit-nA4yOh>pCYFt6ii`isBBTKh3Z7x(o}_OVj2BL*qG>B`lPwloETe%sxW=4#TJ;s zS`XDNlbLMpp|Ul{+N^`R&AP0Iy2JWx9(9);VMkH-n7X0Z$Nt7y%DSzV3)gRddE32k z<>G}e+?%)7*RQT$wi~5>El9J{ypd!<9C=}BZt(AN9{GIwXD~@(ky+_(x@@I9%abgQ zL$tH_E{}pKU!|#mC&oKppZ&&Kv%WujT0B^_Tz3?N+;!Kg{%CE?GcU`;(rn$bwHPNn zT3oiMvX^EH>{UNzd~Gxk++#~NswDJ$zO;Bp+#%^jl=kXq;D>R_m+V!3pZiOGJV|gI zYQ~rM&xSC~F531bUncw{y+dgM)ZgY!TxQl9PknB=>$Y+}l z4zC`E@z4w1SYC2^&iah8pt^6Xn!-&`KYeCZ6uWuKh3m)BC>Wo!u8yotkppEGq~0*( zsg-b%5^F4ygQ+B!i&}jGqt-r;hWTj31!r!YXGxwN+RS4twKCXqAY`S$$d|@pLK?D< zpA~|ym6}t{$&vkO&vByIAsrllG`97!0b-VIVnCjersWZL)tuCOfTH+{1|DW?qn9Y+~yD!+e>W*-&{Lc-T*rcM-N_dWa#be^$RD>MdcrB9<>*(eCfvgwE1 zi>6J-@xo9X$B^APuPWvoxhR;78MaaR?uV#IIJc%4kt`})$mP#B_H z=%Sk`Kd6~XH&ry4ikoT`Ee7qS?r6(L(3N9J3Ne&>74W>#*=iZW0j`1RvoO&MZT4jm%Ef|r~ zbt~oQ@{K|j@1loV zVu%@v`gm3=V@y6C!=*>@wCy-(J3|kcND}E1iLyJBkX}FtywJ$kpEq)U8TtJVmQ{XW zz(z%TYUu6CF7j)iJav}n1Or*x^%#x91h1MEuh2dL=A1ahu{jwJ^aq`yLmpDc1L`#; z0v)_~#H>w>7&Y5EMa8yljJ0aEb-*-|D==mj72`TM?`QP!$0E_|6m9V<`kiX$sEu~F zKE)7!pw}ymTCyW~4n2T(e|-}^DdUj@PzI$|&8{ivD!3mDHa+7wX%LM=?(E=!0x=za zzlyfuu7lUu8*?@Vmqi?B;v}#Ur>Je!?y( zMM|aL1=VXOP_-w9(O26VT!7p_W^x6}6?sfe46w>>tY5lh_XV-0d<~D(VE>UC$VY0B z?IwU#P`E9PxMgSR^Ww?_*Cy1c(m_xx|J_GUvFh7~ZED!m4{6#4# c-G-@=ipS@)r&>o*@jYpuG+#3N=4o@`U#t!7>Hq)$ diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc deleted file mode 100644 index e5ed627f04519fabab3d71d8d54161f33c35548e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5590 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc deleted file mode 100644 index 50ced6efe463bcacaba5ebe1aa4de9c52901c8a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7037 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 V`GRF)BSyv#s^9Xsl{d$i{|j({;k*C< diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc deleted file mode 100644 index ab0b4ce8fad43777772724f7363ee9e2366b9a00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1437 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 LbDp!`)$aWhRfK4R diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc deleted file mode 100644 index 0d2bba9016b4b687e67b3ebb2715645538e795ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1507 zcmZ8h&2Aev5GJ|5mexvYxG+)#DBD9}6|f9Arx-@k)(G05saqs*Pzwfxl}SfybC(;E zYe%YdX^I~E4DzwB(Z}Gmr#wLcU(z9E2Z;%AI6s_O&dfKvzr5T+uzvmXpTU0-LjOA9 z!$m;&2DTmnVTfUY`im3yF~~%aGU$ic=>p)Re(d>BBxTx9G2*Fu0=7sjm92iOZ1>w` z*3aNh%#uG)f0?Ch3C<2{u{NBy7=DJj*<1J;+UsH))w$9fm_+ec4c7+Pm7flNIT-Bz z@M!nP!PEV{y~lgscLSULT$@5xxv=4L{@U1RzXI_HyGU2d@geM8*qQ=ic#2LFl`-@T zP0<`=MlJ{o?w~oo09`lSyTsdXou6`~OKhZTQ9yJd&$)uf1dS4ZBee|H%biVA)|+)v zZ!}e%ADwcxaX#W)Y}{{#<9oxgaJJ1sQ5mk_p_`2t{F=Os4-5C-~a#7piX z>KF(jDGsr^1>8s3xYjtk&*p1j3_8Jc;%P8N7x)6tkO}7z!zP|5UPESh>IzIIqZWm= zE2}fE49#hsn-Mhr)ADK&4*fw#sE_>I?B(ukM*jN zhO@A3`Ac_xF*MKK)se%l136IoQYbEUrOzRld_ zDlhpK7`jBQK;9~I#MNs-I>6bsyErh?Rdf{;i&Dm`cm=CFAb(U!2MR#{qLdS07GSu* z`mO;;oRDK=f;Z?d{09GyT}fRr52G2Lky!u~Pl?)@0&q@=`i_M&QhjCOlY~VezhLo{ ztRc{?n3N?qVlB;EQ!)+KAl@vP2GE*xvVNmA?;En{k4tP(T6G(qI=O!!8+w#iR90e4 zO{1!-7DDEl0@$RNUC}gMucV>Bf#nM|>)ItDk8&}R+E`?x^P;-9H6e$GlZTb8HoVQd z0vH}^nk!D7w{GfMD%WaRQ8OwutwnB*p`+XHBe!i!8;61O0@~gAR%<{RjN>Dvq_VNQ zoEsbaPiXZiq+wI{Tt8cZ9&4Lk2eqvixoEieRBP_0gUZ%54!WUlzr_O^SKL6v1txC7 z0el=9oZIIRM1KhcMH!B9_>Q~_!&Q=z7`I4^kZWDk!D=0Db#JRr;84z`e-}o$H#p-J zld7kS*S%7naovOPfL`Th(x;;W$NA@e<~^>5zUPO&XU26=y;Kf(Hog)Z0+pL+l{n%C p-b2+t;sbp9)I7-3ol>$!@CWYaq}?o}I3*d*Aej)a25FME{|9E|ix~g_ diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc deleted file mode 100644 index 267dc23ce71655530eec4adcd905cb3403506e45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3280 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py b/env/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py deleted file mode 100644 index 3989ed31..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -This code wraps the vendored appdirs module to so the return values are -compatible for the current pip code base. - -The intention is to rewrite current usages gradually, keeping the tests pass, -and eventually drop this after all usages are changed. -""" - -from __future__ import absolute_import - -import os - -from pip._vendor import appdirs as _appdirs - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List - - -def user_cache_dir(appname): - # type: (str) -> str - return _appdirs.user_cache_dir(appname, appauthor=False) - - -def user_config_dir(appname, roaming=True): - # type: (str, bool) -> str - path = _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming) - if _appdirs.system == "darwin" and not os.path.isdir(path): - path = os.path.expanduser('~/.config/') - if appname: - path = os.path.join(path, appname) - return path - - -# for the discussion regarding site_config_dir locations -# see -def site_config_dirs(appname): - # type: (str) -> List[str] - dirval = _appdirs.site_config_dir(appname, appauthor=False, multipath=True) - if _appdirs.system not in ["win32", "darwin"]: - # always look in /etc directly as well - return dirval.split(os.pathsep) + ['/etc'] - return [dirval] diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/compat.py b/env/lib/python3.8/site-packages/pip/_internal/utils/compat.py deleted file mode 100644 index d939e21f..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/compat.py +++ /dev/null @@ -1,270 +0,0 @@ -"""Stuff that differs in different Python versions and platform -distributions.""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import, division - -import codecs -import locale -import logging -import os -import shutil -import sys - -from pip._vendor.six import PY2, text_type - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Text, Tuple, Union - -try: - import ipaddress -except ImportError: - try: - from pip._vendor import ipaddress # type: ignore - except ImportError: - import ipaddr as ipaddress # type: ignore - ipaddress.ip_address = ipaddress.IPAddress # type: ignore - ipaddress.ip_network = ipaddress.IPNetwork # type: ignore - - -__all__ = [ - "ipaddress", "uses_pycache", "console_to_str", - "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", -] - - -logger = logging.getLogger(__name__) - -if PY2: - import imp - - try: - cache_from_source = imp.cache_from_source # type: ignore - except AttributeError: - # does not use __pycache__ - cache_from_source = None - - uses_pycache = cache_from_source is not None -else: - uses_pycache = True - from importlib.util import cache_from_source - - -if PY2: - # In Python 2.7, backslashreplace exists - # but does not support use for decoding. - # We implement our own replace handler for this - # situation, so that we can consistently use - # backslash replacement for all versions. - def backslashreplace_decode_fn(err): - raw_bytes = (err.object[i] for i in range(err.start, err.end)) - # Python 2 gave us characters - convert to numeric bytes - raw_bytes = (ord(b) for b in raw_bytes) - return u"".join(map(u"\\x{:x}".format, raw_bytes)), err.end - codecs.register_error( - "backslashreplace_decode", - backslashreplace_decode_fn, - ) - backslashreplace_decode = "backslashreplace_decode" -else: - backslashreplace_decode = "backslashreplace" - - -def has_tls(): - # type: () -> bool - try: - import _ssl # noqa: F401 # ignore unused - return True - except ImportError: - pass - - from pip._vendor.urllib3.util import IS_PYOPENSSL - return IS_PYOPENSSL - - -def str_to_display(data, desc=None): - # type: (Union[bytes, Text], Optional[str]) -> Text - """ - For display or logging purposes, convert a bytes object (or text) to - text (e.g. unicode in Python 2) safe for output. - - :param desc: An optional phrase describing the input data, for use in - the log message if a warning is logged. Defaults to "Bytes object". - - This function should never error out and so can take a best effort - approach. It is okay to be lossy if needed since the return value is - just for display. - - We assume the data is in the locale preferred encoding. If it won't - decode properly, we warn the user but decode as best we can. - - We also ensure that the output can be safely written to standard output - without encoding errors. - """ - if isinstance(data, text_type): - return data - - # Otherwise, data is a bytes object (str in Python 2). - # First, get the encoding we assume. This is the preferred - # encoding for the locale, unless that is not found, or - # it is ASCII, in which case assume UTF-8 - encoding = locale.getpreferredencoding() - if (not encoding) or codecs.lookup(encoding).name == "ascii": - encoding = "utf-8" - - # Now try to decode the data - if we fail, warn the user and - # decode with replacement. - try: - decoded_data = data.decode(encoding) - except UnicodeDecodeError: - if desc is None: - desc = 'Bytes object' - msg_format = '{} does not appear to be encoded as %s'.format(desc) - logger.warning(msg_format, encoding) - decoded_data = data.decode(encoding, errors=backslashreplace_decode) - - # Make sure we can print the output, by encoding it to the output - # encoding with replacement of unencodable characters, and then - # decoding again. - # We use stderr's encoding because it's less likely to be - # redirected and if we don't find an encoding we skip this - # step (on the assumption that output is wrapped by something - # that won't fail). - # The double getattr is to deal with the possibility that we're - # being called in a situation where sys.__stderr__ doesn't exist, - # or doesn't have an encoding attribute. Neither of these cases - # should occur in normal pip use, but there's no harm in checking - # in case people use pip in (unsupported) unusual situations. - output_encoding = getattr(getattr(sys, "__stderr__", None), - "encoding", None) - - if output_encoding: - output_encoded = decoded_data.encode( - output_encoding, - errors="backslashreplace" - ) - decoded_data = output_encoded.decode(output_encoding) - - return decoded_data - - -def console_to_str(data): - # type: (bytes) -> Text - """Return a string, safe for output, of subprocess output. - """ - return str_to_display(data, desc='Subprocess output') - - -def get_path_uid(path): - # type: (str) -> int - """ - Return path's uid. - - Does not follow symlinks: - https://github.com/pypa/pip/pull/935#discussion_r5307003 - - Placed this function in compat due to differences on AIX and - Jython, that should eventually go away. - - :raises OSError: When path is a symlink or can't be read. - """ - if hasattr(os, 'O_NOFOLLOW'): - fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) - file_uid = os.fstat(fd).st_uid - os.close(fd) - else: # AIX and Jython - # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW - if not os.path.islink(path): - # older versions of Jython don't have `os.fstat` - file_uid = os.stat(path).st_uid - else: - # raise OSError for parity with os.O_NOFOLLOW above - raise OSError( - "{} is a symlink; Will not return uid for symlinks".format( - path) - ) - return file_uid - - -def expanduser(path): - # type: (str) -> str - """ - Expand ~ and ~user constructions. - - Includes a workaround for https://bugs.python.org/issue14768 - """ - expanded = os.path.expanduser(path) - if path.startswith('~/') and expanded.startswith('//'): - expanded = expanded[1:] - return expanded - - -# packages in the stdlib that may have installation metadata, but should not be -# considered 'installed'. this theoretically could be determined based on -# dist.location (py27:`sysconfig.get_paths()['stdlib']`, -# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may -# make this ineffective, so hard-coding -stdlib_pkgs = {"python", "wsgiref", "argparse"} - - -# windows detection, covers cpython and ironpython -WINDOWS = (sys.platform.startswith("win") or - (sys.platform == 'cli' and os.name == 'nt')) - - -def samefile(file1, file2): - # type: (str, str) -> bool - """Provide an alternative for os.path.samefile on Windows/Python2""" - if hasattr(os.path, 'samefile'): - return os.path.samefile(file1, file2) - else: - path1 = os.path.normcase(os.path.abspath(file1)) - path2 = os.path.normcase(os.path.abspath(file2)) - return path1 == path2 - - -if hasattr(shutil, 'get_terminal_size'): - def get_terminal_size(): - # type: () -> Tuple[int, int] - """ - Returns a tuple (x, y) representing the width(x) and the height(y) - in characters of the terminal window. - """ - return tuple(shutil.get_terminal_size()) # type: ignore -else: - def get_terminal_size(): - # type: () -> Tuple[int, int] - """ - Returns a tuple (x, y) representing the width(x) and the height(y) - in characters of the terminal window. - """ - def ioctl_GWINSZ(fd): - try: - import fcntl - import termios - import struct - cr = struct.unpack_from( - 'hh', - fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') - ) - except Exception: - return None - if cr == (0, 0): - return None - return cr - cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) - if not cr: - if sys.platform != "win32": - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except Exception: - pass - if not cr: - cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) - return int(cr[1]), int(cr[0]) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/compatibility_tags.py b/env/lib/python3.8/site-packages/pip/_internal/utils/compatibility_tags.py deleted file mode 100644 index 47d04f07..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/compatibility_tags.py +++ /dev/null @@ -1,169 +0,0 @@ -"""Generate and work with PEP 425 Compatibility Tags. -""" - -from __future__ import absolute_import - -import logging -import re - -from pip._vendor.packaging.tags import ( - Tag, - compatible_tags, - cpython_tags, - generic_tags, - interpreter_name, - interpreter_version, - mac_platforms, -) - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Tuple - - from pip._vendor.packaging.tags import PythonVersion - -logger = logging.getLogger(__name__) - -_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') - - -def version_info_to_nodot(version_info): - # type: (Tuple[int, ...]) -> str - # Only use up to the first two numbers. - return ''.join(map(str, version_info[:2])) - - -def _mac_platforms(arch): - # type: (str) -> List[str] - match = _osx_arch_pat.match(arch) - if match: - name, major, minor, actual_arch = match.groups() - mac_version = (int(major), int(minor)) - arches = [ - # Since we have always only checked that the platform starts - # with "macosx", for backwards-compatibility we extract the - # actual prefix provided by the user in case they provided - # something like "macosxcustom_". It may be good to remove - # this as undocumented or deprecate it in the future. - '{}_{}'.format(name, arch[len('macosx_'):]) - for arch in mac_platforms(mac_version, actual_arch) - ] - else: - # arch pattern didn't match (?!) - arches = [arch] - return arches - - -def _custom_manylinux_platforms(arch): - # type: (str) -> List[str] - arches = [arch] - arch_prefix, arch_sep, arch_suffix = arch.partition('_') - if arch_prefix == 'manylinux2014': - # manylinux1/manylinux2010 wheels run on most manylinux2014 systems - # with the exception of wheels depending on ncurses. PEP 599 states - # manylinux1/manylinux2010 wheels should be considered - # manylinux2014 wheels: - # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels - if arch_suffix in {'i686', 'x86_64'}: - arches.append('manylinux2010' + arch_sep + arch_suffix) - arches.append('manylinux1' + arch_sep + arch_suffix) - elif arch_prefix == 'manylinux2010': - # manylinux1 wheels run on most manylinux2010 systems with the - # exception of wheels depending on ncurses. PEP 571 states - # manylinux1 wheels should be considered manylinux2010 wheels: - # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels - arches.append('manylinux1' + arch_sep + arch_suffix) - return arches - - -def _get_custom_platforms(arch): - # type: (str) -> List[str] - arch_prefix, arch_sep, arch_suffix = arch.partition('_') - if arch.startswith('macosx'): - arches = _mac_platforms(arch) - elif arch_prefix in ['manylinux2014', 'manylinux2010']: - arches = _custom_manylinux_platforms(arch) - else: - arches = [arch] - return arches - - -def _get_python_version(version): - # type: (str) -> PythonVersion - if len(version) > 1: - return int(version[0]), int(version[1:]) - else: - return (int(version[0]),) - - -def _get_custom_interpreter(implementation=None, version=None): - # type: (Optional[str], Optional[str]) -> str - if implementation is None: - implementation = interpreter_name() - if version is None: - version = interpreter_version() - return "{}{}".format(implementation, version) - - -def get_supported( - version=None, # type: Optional[str] - platform=None, # type: Optional[str] - impl=None, # type: Optional[str] - abi=None # type: Optional[str] -): - # type: (...) -> List[Tag] - """Return a list of supported tags for each version specified in - `versions`. - - :param version: a string version, of the form "33" or "32", - or None. The version will be assumed to support our ABI. - :param platform: specify the exact platform you want valid - tags for, or None. If None, use the local system platform. - :param impl: specify the exact implementation you want valid - tags for, or None. If None, use the local interpreter impl. - :param abi: specify the exact abi you want valid - tags for, or None. If None, use the local interpreter abi. - """ - supported = [] # type: List[Tag] - - python_version = None # type: Optional[PythonVersion] - if version is not None: - python_version = _get_python_version(version) - - interpreter = _get_custom_interpreter(impl, version) - - abis = None # type: Optional[List[str]] - if abi is not None: - abis = [abi] - - platforms = None # type: Optional[List[str]] - if platform is not None: - platforms = _get_custom_platforms(platform) - - is_cpython = (impl or interpreter_name()) == "cp" - if is_cpython: - supported.extend( - cpython_tags( - python_version=python_version, - abis=abis, - platforms=platforms, - ) - ) - else: - supported.extend( - generic_tags( - interpreter=interpreter, - abis=abis, - platforms=platforms, - ) - ) - supported.extend( - compatible_tags( - python_version=python_version, - interpreter=interpreter, - platforms=platforms, - ) - ) - - return supported diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py b/env/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py deleted file mode 100644 index 2f20cfd4..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -A module that implements tooling to enable easy warnings about deprecations. -""" - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import warnings - -from pip._vendor.packaging.version import parse - -from pip import __version__ as current_version -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Optional - - -DEPRECATION_MSG_PREFIX = "DEPRECATION: " - - -class PipDeprecationWarning(Warning): - pass - - -_original_showwarning = None # type: Any - - -# Warnings <-> Logging Integration -def _showwarning(message, category, filename, lineno, file=None, line=None): - if file is not None: - if _original_showwarning is not None: - _original_showwarning( - message, category, filename, lineno, file, line, - ) - elif issubclass(category, PipDeprecationWarning): - # We use a specially named logger which will handle all of the - # deprecation messages for pip. - logger = logging.getLogger("pip._internal.deprecations") - logger.warning(message) - else: - _original_showwarning( - message, category, filename, lineno, file, line, - ) - - -def install_warning_logger(): - # type: () -> None - # Enable our Deprecation Warnings - warnings.simplefilter("default", PipDeprecationWarning, append=True) - - global _original_showwarning - - if _original_showwarning is None: - _original_showwarning = warnings.showwarning - warnings.showwarning = _showwarning - - -def deprecated(reason, replacement, gone_in, issue=None): - # type: (str, Optional[str], Optional[str], Optional[int]) -> None - """Helper to deprecate existing functionality. - - reason: - Textual reason shown to the user about why this functionality has - been deprecated. - replacement: - Textual suggestion shown to the user about what alternative - functionality they can use. - gone_in: - The version of pip does this functionality should get removed in. - Raises errors if pip's current version is greater than or equal to - this. - issue: - Issue number on the tracker that would serve as a useful place for - users to find related discussion and provide feedback. - - Always pass replacement, gone_in and issue as keyword arguments for clarity - at the call site. - """ - - # Construct a nice message. - # This is eagerly formatted as we want it to get logged as if someone - # typed this entire message out. - sentences = [ - (reason, DEPRECATION_MSG_PREFIX + "{}"), - (gone_in, "pip {} will remove support for this functionality."), - (replacement, "A possible replacement is {}."), - (issue, ( - "You can find discussion regarding this at " - "https://github.com/pypa/pip/issues/{}." - )), - ] - message = " ".join( - template.format(val) for val, template in sentences if val is not None - ) - - # Raise as an error if it has to be removed. - if gone_in is not None and parse(current_version) >= parse(gone_in): - raise PipDeprecationWarning(message) - - warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/direct_url_helpers.py b/env/lib/python3.8/site-packages/pip/_internal/utils/direct_url_helpers.py deleted file mode 100644 index f1fe209e..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/direct_url_helpers.py +++ /dev/null @@ -1,130 +0,0 @@ -import logging - -from pip._internal.models.direct_url import ( - DIRECT_URL_METADATA_NAME, - ArchiveInfo, - DirectUrl, - DirectUrlValidationError, - DirInfo, - VcsInfo, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs import vcs - -try: - from json import JSONDecodeError -except ImportError: - # PY2 - JSONDecodeError = ValueError # type: ignore - -if MYPY_CHECK_RUNNING: - from typing import Optional - - from pip._internal.models.link import Link - - from pip._vendor.pkg_resources import Distribution - -logger = logging.getLogger(__name__) - - -def direct_url_as_pep440_direct_reference(direct_url, name): - # type: (DirectUrl, str) -> str - """Convert a DirectUrl to a pip requirement string.""" - direct_url.validate() # if invalid, this is a pip bug - requirement = name + " @ " - fragments = [] - if isinstance(direct_url.info, VcsInfo): - requirement += "{}+{}@{}".format( - direct_url.info.vcs, direct_url.url, direct_url.info.commit_id - ) - elif isinstance(direct_url.info, ArchiveInfo): - requirement += direct_url.url - if direct_url.info.hash: - fragments.append(direct_url.info.hash) - else: - assert isinstance(direct_url.info, DirInfo) - # pip should never reach this point for editables, since - # pip freeze inspects the editable project location to produce - # the requirement string - assert not direct_url.info.editable - requirement += direct_url.url - if direct_url.subdirectory: - fragments.append("subdirectory=" + direct_url.subdirectory) - if fragments: - requirement += "#" + "&".join(fragments) - return requirement - - -def direct_url_from_link(link, source_dir=None, link_is_in_wheel_cache=False): - # type: (Link, Optional[str], bool) -> DirectUrl - if link.is_vcs: - vcs_backend = vcs.get_backend_for_scheme(link.scheme) - assert vcs_backend - url, requested_revision, _ = ( - vcs_backend.get_url_rev_and_auth(link.url_without_fragment) - ) - # For VCS links, we need to find out and add commit_id. - if link_is_in_wheel_cache: - # If the requested VCS link corresponds to a cached - # wheel, it means the requested revision was an - # immutable commit hash, otherwise it would not have - # been cached. In that case we don't have a source_dir - # with the VCS checkout. - assert requested_revision - commit_id = requested_revision - else: - # If the wheel was not in cache, it means we have - # had to checkout from VCS to build and we have a source_dir - # which we can inspect to find out the commit id. - assert source_dir - commit_id = vcs_backend.get_revision(source_dir) - return DirectUrl( - url=url, - info=VcsInfo( - vcs=vcs_backend.name, - commit_id=commit_id, - requested_revision=requested_revision, - ), - subdirectory=link.subdirectory_fragment, - ) - elif link.is_existing_dir(): - return DirectUrl( - url=link.url_without_fragment, - info=DirInfo(), - subdirectory=link.subdirectory_fragment, - ) - else: - hash = None - hash_name = link.hash_name - if hash_name: - hash = "{}={}".format(hash_name, link.hash) - return DirectUrl( - url=link.url_without_fragment, - info=ArchiveInfo(hash=hash), - subdirectory=link.subdirectory_fragment, - ) - - -def dist_get_direct_url(dist): - # type: (Distribution) -> Optional[DirectUrl] - """Obtain a DirectUrl from a pkg_resource.Distribution. - - Returns None if the distribution has no `direct_url.json` metadata, - or if `direct_url.json` is invalid. - """ - if not dist.has_metadata(DIRECT_URL_METADATA_NAME): - return None - try: - return DirectUrl.from_json(dist.get_metadata(DIRECT_URL_METADATA_NAME)) - except ( - DirectUrlValidationError, - JSONDecodeError, - UnicodeDecodeError - ) as e: - logger.warning( - "Error parsing %s for %s: %s", - DIRECT_URL_METADATA_NAME, - dist.project_name, - e, - ) - return None diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/distutils_args.py b/env/lib/python3.8/site-packages/pip/_internal/utils/distutils_args.py deleted file mode 100644 index e38e402d..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/distutils_args.py +++ /dev/null @@ -1,48 +0,0 @@ -from distutils.errors import DistutilsArgError -from distutils.fancy_getopt import FancyGetopt - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Dict, List - - -_options = [ - ("exec-prefix=", None, ""), - ("home=", None, ""), - ("install-base=", None, ""), - ("install-data=", None, ""), - ("install-headers=", None, ""), - ("install-lib=", None, ""), - ("install-platlib=", None, ""), - ("install-purelib=", None, ""), - ("install-scripts=", None, ""), - ("prefix=", None, ""), - ("root=", None, ""), - ("user", None, ""), -] - - -# typeshed doesn't permit Tuple[str, None, str], see python/typeshed#3469. -_distutils_getopt = FancyGetopt(_options) # type: ignore - - -def parse_distutils_args(args): - # type: (List[str]) -> Dict[str, str] - """Parse provided arguments, returning an object that has the - matched arguments. - - Any unknown arguments are ignored. - """ - result = {} - for arg in args: - try: - _, match = _distutils_getopt.getopt(args=[arg]) - except DistutilsArgError: - # We don't care about any other options, which here may be - # considered unrecognized since our option list is not - # exhaustive. - pass - else: - result.update(match.__dict__) - return result diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/encoding.py b/env/lib/python3.8/site-packages/pip/_internal/utils/encoding.py deleted file mode 100644 index ab4d4b98..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/encoding.py +++ /dev/null @@ -1,42 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import codecs -import locale -import re -import sys - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Tuple, Text - -BOMS = [ - (codecs.BOM_UTF8, 'utf-8'), - (codecs.BOM_UTF16, 'utf-16'), - (codecs.BOM_UTF16_BE, 'utf-16-be'), - (codecs.BOM_UTF16_LE, 'utf-16-le'), - (codecs.BOM_UTF32, 'utf-32'), - (codecs.BOM_UTF32_BE, 'utf-32-be'), - (codecs.BOM_UTF32_LE, 'utf-32-le'), -] # type: List[Tuple[bytes, Text]] - -ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') - - -def auto_decode(data): - # type: (bytes) -> Text - """Check a bytes string for a BOM to correctly detect the encoding - - Fallback to locale.getpreferredencoding(False) like open() on Python3""" - for bom, encoding in BOMS: - if data.startswith(bom): - return data[len(bom):].decode(encoding) - # Lets check the first two lines as in PEP263 - for line in data.split(b'\n')[:2]: - if line[0:1] == b'#' and ENCODING_RE.search(line): - encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') - return data.decode(encoding) - return data.decode( - locale.getpreferredencoding(False) or sys.getdefaultencoding(), - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/entrypoints.py b/env/lib/python3.8/site-packages/pip/_internal/utils/entrypoints.py deleted file mode 100644 index befd01c8..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/entrypoints.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys - -from pip._internal.cli.main import main -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, List - - -def _wrapper(args=None): - # type: (Optional[List[str]]) -> int - """Central wrapper for all old entrypoints. - - Historically pip has had several entrypoints defined. Because of issues - arising from PATH, sys.path, multiple Pythons, their interactions, and most - of them having a pip installed, users suffer every time an entrypoint gets - moved. - - To alleviate this pain, and provide a mechanism for warning users and - directing them to an appropriate place for help, we now define all of - our old entrypoints as wrappers for the current one. - """ - sys.stderr.write( - "WARNING: pip is being invoked by an old script wrapper. This will " - "fail in a future version of pip.\n" - "Please see https://github.com/pypa/pip/issues/5599 for advice on " - "fixing the underlying issue.\n" - "To avoid this problem you can invoke Python with '-m pip' instead of " - "running pip directly.\n" - ) - return main(args) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py b/env/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py deleted file mode 100644 index 437a7fd1..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py +++ /dev/null @@ -1,222 +0,0 @@ -import errno -import fnmatch -import os -import os.path -import random -import shutil -import stat -import sys -from contextlib import contextmanager -from tempfile import NamedTemporaryFile - -# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import. -from pip._vendor.retrying import retry # type: ignore -from pip._vendor.six import PY2 - -from pip._internal.utils.compat import get_path_uid -from pip._internal.utils.misc import format_size -from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast - -if MYPY_CHECK_RUNNING: - from typing import Any, BinaryIO, Iterator, List, Union - - class NamedTemporaryFileResult(BinaryIO): - @property - def file(self): - # type: () -> BinaryIO - pass - - -def check_path_owner(path): - # type: (str) -> bool - # If we don't have a way to check the effective uid of this process, then - # we'll just assume that we own the directory. - if sys.platform == "win32" or not hasattr(os, "geteuid"): - return True - - assert os.path.isabs(path) - - previous = None - while path != previous: - if os.path.lexists(path): - # Check if path is writable by current user. - if os.geteuid() == 0: - # Special handling for root user in order to handle properly - # cases where users use sudo without -H flag. - try: - path_uid = get_path_uid(path) - except OSError: - return False - return path_uid == 0 - else: - return os.access(path, os.W_OK) - else: - previous, path = path, os.path.dirname(path) - return False # assume we don't own the path - - -def copy2_fixed(src, dest): - # type: (str, str) -> None - """Wrap shutil.copy2() but map errors copying socket files to - SpecialFileError as expected. - - See also https://bugs.python.org/issue37700. - """ - try: - shutil.copy2(src, dest) - except (OSError, IOError): - for f in [src, dest]: - try: - is_socket_file = is_socket(f) - except OSError: - # An error has already occurred. Another error here is not - # a problem and we can ignore it. - pass - else: - if is_socket_file: - raise shutil.SpecialFileError( - "`{f}` is a socket".format(**locals())) - - raise - - -def is_socket(path): - # type: (str) -> bool - return stat.S_ISSOCK(os.lstat(path).st_mode) - - -@contextmanager -def adjacent_tmp_file(path, **kwargs): - # type: (str, **Any) -> Iterator[NamedTemporaryFileResult] - """Return a file-like object pointing to a tmp file next to path. - - The file is created securely and is ensured to be written to disk - after the context reaches its end. - - kwargs will be passed to tempfile.NamedTemporaryFile to control - the way the temporary file will be opened. - """ - with NamedTemporaryFile( - delete=False, - dir=os.path.dirname(path), - prefix=os.path.basename(path), - suffix='.tmp', - **kwargs - ) as f: - result = cast('NamedTemporaryFileResult', f) - try: - yield result - finally: - result.file.flush() - os.fsync(result.file.fileno()) - - -_replace_retry = retry(stop_max_delay=1000, wait_fixed=250) - -if PY2: - @_replace_retry - def replace(src, dest): - # type: (str, str) -> None - try: - os.rename(src, dest) - except OSError: - os.remove(dest) - os.rename(src, dest) - -else: - replace = _replace_retry(os.replace) - - -# test_writable_dir and _test_writable_dir_win are copied from Flit, -# with the author's agreement to also place them under pip's license. -def test_writable_dir(path): - # type: (str) -> bool - """Check if a directory is writable. - - Uses os.access() on POSIX, tries creating files on Windows. - """ - # If the directory doesn't exist, find the closest parent that does. - while not os.path.isdir(path): - parent = os.path.dirname(path) - if parent == path: - break # Should never get here, but infinite loops are bad - path = parent - - if os.name == 'posix': - return os.access(path, os.W_OK) - - return _test_writable_dir_win(path) - - -def _test_writable_dir_win(path): - # type: (str) -> bool - # os.access doesn't work on Windows: http://bugs.python.org/issue2528 - # and we can't use tempfile: http://bugs.python.org/issue22107 - basename = 'accesstest_deleteme_fishfingers_custard_' - alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789' - for i in range(10): - name = basename + ''.join(random.choice(alphabet) for _ in range(6)) - file = os.path.join(path, name) - try: - fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL) - # Python 2 doesn't support FileExistsError and PermissionError. - except OSError as e: - # exception FileExistsError - if e.errno == errno.EEXIST: - continue - # exception PermissionError - if e.errno == errno.EPERM or e.errno == errno.EACCES: - # This could be because there's a directory with the same name. - # But it's highly unlikely there's a directory called that, - # so we'll assume it's because the parent dir is not writable. - return False - raise - else: - os.close(fd) - os.unlink(file) - return True - - # This should never be reached - raise EnvironmentError( - 'Unexpected condition testing for writable directory' - ) - - -def find_files(path, pattern): - # type: (str, str) -> List[str] - """Returns a list of absolute paths of files beneath path, recursively, - with filenames which match the UNIX-style shell glob pattern.""" - result = [] # type: List[str] - for root, dirs, files in os.walk(path): - matches = fnmatch.filter(files, pattern) - result.extend(os.path.join(root, f) for f in matches) - return result - - -def file_size(path): - # type: (str) -> Union[int, float] - # If it's a symlink, return 0. - if os.path.islink(path): - return 0 - return os.path.getsize(path) - - -def format_file_size(path): - # type: (str) -> str - return format_size(file_size(path)) - - -def directory_size(path): - # type: (str) -> Union[int, float] - size = 0.0 - for root, _dirs, files in os.walk(path): - for filename in files: - file_path = os.path.join(root, filename) - size += file_size(file_path) - return size - - -def format_directory_size(path): - # type: (str) -> str - return format_size(directory_size(path)) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/filetypes.py b/env/lib/python3.8/site-packages/pip/_internal/utils/filetypes.py deleted file mode 100644 index daa0ca77..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/filetypes.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Filetype information. -""" -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Tuple - -WHEEL_EXTENSION = '.whl' -BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') # type: Tuple[str, ...] -XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', - '.tar.lz', '.tar.lzma') # type: Tuple[str, ...] -ZIP_EXTENSIONS = ('.zip', WHEEL_EXTENSION) # type: Tuple[str, ...] -TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') # type: Tuple[str, ...] -ARCHIVE_EXTENSIONS = ( - ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS -) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/glibc.py b/env/lib/python3.8/site-packages/pip/_internal/utils/glibc.py deleted file mode 100644 index 36104244..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/glibc.py +++ /dev/null @@ -1,98 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import os -import sys - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple - - -def glibc_version_string(): - # type: () -> Optional[str] - "Returns glibc version string, or None if not using glibc." - return glibc_version_string_confstr() or glibc_version_string_ctypes() - - -def glibc_version_string_confstr(): - # type: () -> Optional[str] - "Primary implementation of glibc_version_string using os.confstr." - # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely - # to be broken or missing. This strategy is used in the standard library - # platform module: - # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183 - if sys.platform == "win32": - return None - try: - # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17": - _, version = os.confstr("CS_GNU_LIBC_VERSION").split() - except (AttributeError, OSError, ValueError): - # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... - return None - return version - - -def glibc_version_string_ctypes(): - # type: () -> Optional[str] - "Fallback implementation of glibc_version_string using ctypes." - - try: - import ctypes - except ImportError: - return None - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen - # manpage says, "If filename is NULL, then the returned handle is for the - # main program". This way we can let the linker do the work to figure out - # which libc our process is actually using. - process_namespace = ctypes.CDLL(None) - try: - gnu_get_libc_version = process_namespace.gnu_get_libc_version - except AttributeError: - # Symbol doesn't exist -> therefore, we are not linked to - # glibc. - return None - - # Call gnu_get_libc_version, which returns a string like "2.5" - gnu_get_libc_version.restype = ctypes.c_char_p - version_str = gnu_get_libc_version() - # py2 / py3 compatibility: - if not isinstance(version_str, str): - version_str = version_str.decode("ascii") - - return version_str - - -# platform.libc_ver regularly returns completely nonsensical glibc -# versions. E.g. on my computer, platform says: -# -# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.7') -# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.9') -# -# But the truth is: -# -# ~$ ldd --version -# ldd (Debian GLIBC 2.22-11) 2.22 -# -# This is unfortunate, because it means that the linehaul data on libc -# versions that was generated by pip 8.1.2 and earlier is useless and -# misleading. Solution: instead of using platform, use our code that actually -# works. -def libc_ver(): - # type: () -> Tuple[str, str] - """Try to determine the glibc version - - Returns a tuple of strings (lib, version) which default to empty strings - in case the lookup fails. - """ - glibc_version = glibc_version_string() - if glibc_version is None: - return ("", "") - else: - return ("glibc", glibc_version) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/hashes.py b/env/lib/python3.8/site-packages/pip/_internal/utils/hashes.py deleted file mode 100644 index 396cf82e..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/hashes.py +++ /dev/null @@ -1,133 +0,0 @@ -from __future__ import absolute_import - -import hashlib - -from pip._vendor.six import iteritems, iterkeys, itervalues - -from pip._internal.exceptions import ( - HashMismatch, - HashMissing, - InstallationError, -) -from pip._internal.utils.misc import read_chunks -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Dict, List, BinaryIO, NoReturn, Iterator - ) - from pip._vendor.six import PY3 - if PY3: - from hashlib import _Hash - else: - from hashlib import _hash as _Hash - - -# The recommended hash algo of the moment. Change this whenever the state of -# the art changes; it won't hurt backward compatibility. -FAVORITE_HASH = 'sha256' - - -# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` -# Currently, those are the ones at least as collision-resistant as sha256. -STRONG_HASHES = ['sha256', 'sha384', 'sha512'] - - -class Hashes(object): - """A wrapper that builds multiple hashes at once and checks them against - known-good values - - """ - def __init__(self, hashes=None): - # type: (Dict[str, List[str]]) -> None - """ - :param hashes: A dict of algorithm names pointing to lists of allowed - hex digests - """ - self._allowed = {} if hashes is None else hashes - - @property - def digest_count(self): - # type: () -> int - return sum(len(digests) for digests in self._allowed.values()) - - def is_hash_allowed( - self, - hash_name, # type: str - hex_digest, # type: str - ): - # type: (...) -> bool - """Return whether the given hex digest is allowed.""" - return hex_digest in self._allowed.get(hash_name, []) - - def check_against_chunks(self, chunks): - # type: (Iterator[bytes]) -> None - """Check good hashes against ones built from iterable of chunks of - data. - - Raise HashMismatch if none match. - - """ - gots = {} - for hash_name in iterkeys(self._allowed): - try: - gots[hash_name] = hashlib.new(hash_name) - except (ValueError, TypeError): - raise InstallationError( - 'Unknown hash name: {}'.format(hash_name) - ) - - for chunk in chunks: - for hash in itervalues(gots): - hash.update(chunk) - - for hash_name, got in iteritems(gots): - if got.hexdigest() in self._allowed[hash_name]: - return - self._raise(gots) - - def _raise(self, gots): - # type: (Dict[str, _Hash]) -> NoReturn - raise HashMismatch(self._allowed, gots) - - def check_against_file(self, file): - # type: (BinaryIO) -> None - """Check good hashes against a file-like object - - Raise HashMismatch if none match. - - """ - return self.check_against_chunks(read_chunks(file)) - - def check_against_path(self, path): - # type: (str) -> None - with open(path, 'rb') as file: - return self.check_against_file(file) - - def __nonzero__(self): - # type: () -> bool - """Return whether I know any known-good hashes.""" - return bool(self._allowed) - - def __bool__(self): - # type: () -> bool - return self.__nonzero__() - - -class MissingHashes(Hashes): - """A workalike for Hashes used when we're missing a hash for a requirement - - It computes the actual hash of the requirement and raises a HashMissing - exception showing it to the user. - - """ - def __init__(self): - # type: () -> None - """Don't offer the ``hashes`` kwarg.""" - # Pass our favorite hash in to generate a "gotten hash". With the - # empty list, it will never match, so an error will always raise. - super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) - - def _raise(self, gots): - # type: (Dict[str, _Hash]) -> NoReturn - raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/inject_securetransport.py b/env/lib/python3.8/site-packages/pip/_internal/utils/inject_securetransport.py deleted file mode 100644 index 5b93b1d6..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/inject_securetransport.py +++ /dev/null @@ -1,36 +0,0 @@ -"""A helper module that injects SecureTransport, on import. - -The import should be done as early as possible, to ensure all requests and -sessions (or whatever) are created after injecting SecureTransport. - -Note that we only do the injection on macOS, when the linked OpenSSL is too -old to handle TLSv1.2. -""" - -import sys - - -def inject_securetransport(): - # type: () -> None - # Only relevant on macOS - if sys.platform != "darwin": - return - - try: - import ssl - except ImportError: - return - - # Checks for OpenSSL 1.0.1 - if ssl.OPENSSL_VERSION_NUMBER >= 0x1000100f: - return - - try: - from pip._vendor.urllib3.contrib import securetransport - except (ImportError, OSError): - return - - securetransport.inject_into_urllib3() - - -inject_securetransport() diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/logging.py b/env/lib/python3.8/site-packages/pip/_internal/utils/logging.py deleted file mode 100644 index 9a017cf7..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/logging.py +++ /dev/null @@ -1,399 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import contextlib -import errno -import logging -import logging.handlers -import os -import sys -from logging import Filter, getLogger - -from pip._vendor.six import PY2 - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX -from pip._internal.utils.misc import ensure_dir - -try: - import threading -except ImportError: - import dummy_threading as threading # type: ignore - - -try: - # Use "import as" and set colorama in the else clause to avoid mypy - # errors and get the following correct revealed type for colorama: - # `Union[_importlib_modulespec.ModuleType, None]` - # Otherwise, we get an error like the following in the except block: - # > Incompatible types in assignment (expression has type "None", - # variable has type Module) - # TODO: eliminate the need to use "import as" once mypy addresses some - # of its issues with conditional imports. Here is an umbrella issue: - # https://github.com/python/mypy/issues/1297 - from pip._vendor import colorama as _colorama -# Lots of different errors can come from this, including SystemError and -# ImportError. -except Exception: - colorama = None -else: - # Import Fore explicitly rather than accessing below as colorama.Fore - # to avoid the following error running mypy: - # > Module has no attribute "Fore" - # TODO: eliminate the need to import Fore once mypy addresses some of its - # issues with conditional imports. This particular case could be an - # instance of the following issue (but also see the umbrella issue above): - # https://github.com/python/mypy/issues/3500 - from pip._vendor.colorama import Fore - - colorama = _colorama - - -_log_state = threading.local() -subprocess_logger = getLogger('pip.subprocessor') - - -class BrokenStdoutLoggingError(Exception): - """ - Raised if BrokenPipeError occurs for the stdout stream while logging. - """ - pass - - -# BrokenPipeError does not exist in Python 2 and, in addition, manifests -# differently in Windows and non-Windows. -if WINDOWS: - # In Windows, a broken pipe can show up as EINVAL rather than EPIPE: - # https://bugs.python.org/issue19612 - # https://bugs.python.org/issue30418 - if PY2: - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return (exc_class is IOError and - exc.errno in (errno.EINVAL, errno.EPIPE)) - else: - # In Windows, a broken pipe IOError became OSError in Python 3. - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return ((exc_class is BrokenPipeError) or # noqa: F821 - (exc_class is OSError and - exc.errno in (errno.EINVAL, errno.EPIPE))) -elif PY2: - def _is_broken_pipe_error(exc_class, exc): - """See the docstring for non-Windows Python 3 below.""" - return (exc_class is IOError and exc.errno == errno.EPIPE) -else: - # Then we are in the non-Windows Python 3 case. - def _is_broken_pipe_error(exc_class, exc): - """ - Return whether an exception is a broken pipe error. - - Args: - exc_class: an exception class. - exc: an exception instance. - """ - return (exc_class is BrokenPipeError) # noqa: F821 - - -@contextlib.contextmanager -def indent_log(num=2): - """ - A context manager which will cause the log output to be indented for any - log messages emitted inside it. - """ - # For thread-safety - _log_state.indentation = get_indentation() - _log_state.indentation += num - try: - yield - finally: - _log_state.indentation -= num - - -def get_indentation(): - return getattr(_log_state, 'indentation', 0) - - -class IndentingFormatter(logging.Formatter): - - def __init__(self, *args, **kwargs): - """ - A logging.Formatter that obeys the indent_log() context manager. - - :param add_timestamp: A bool indicating output lines should be prefixed - with their record's timestamp. - """ - self.add_timestamp = kwargs.pop("add_timestamp", False) - super(IndentingFormatter, self).__init__(*args, **kwargs) - - def get_message_start(self, formatted, levelno): - """ - Return the start of the formatted log message (not counting the - prefix to add to each line). - """ - if levelno < logging.WARNING: - return '' - if formatted.startswith(DEPRECATION_MSG_PREFIX): - # Then the message already has a prefix. We don't want it to - # look like "WARNING: DEPRECATION: ...." - return '' - if levelno < logging.ERROR: - return 'WARNING: ' - - return 'ERROR: ' - - def format(self, record): - """ - Calls the standard formatter, but will indent all of the log message - lines by our current indentation level. - """ - formatted = super(IndentingFormatter, self).format(record) - message_start = self.get_message_start(formatted, record.levelno) - formatted = message_start + formatted - - prefix = '' - if self.add_timestamp: - # TODO: Use Formatter.default_time_format after dropping PY2. - t = self.formatTime(record, "%Y-%m-%dT%H:%M:%S") - prefix = '{t},{record.msecs:03.0f} '.format(**locals()) - prefix += " " * get_indentation() - formatted = "".join([ - prefix + line - for line in formatted.splitlines(True) - ]) - return formatted - - -def _color_wrap(*colors): - def wrapped(inp): - return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) - return wrapped - - -class ColorizedStreamHandler(logging.StreamHandler): - - # Don't build up a list of colors if we don't have colorama - if colorama: - COLORS = [ - # This needs to be in order from highest logging level to lowest. - (logging.ERROR, _color_wrap(Fore.RED)), - (logging.WARNING, _color_wrap(Fore.YELLOW)), - ] - else: - COLORS = [] - - def __init__(self, stream=None, no_color=None): - logging.StreamHandler.__init__(self, stream) - self._no_color = no_color - - if WINDOWS and colorama: - self.stream = colorama.AnsiToWin32(self.stream) - - def _using_stdout(self): - """ - Return whether the handler is using sys.stdout. - """ - if WINDOWS and colorama: - # Then self.stream is an AnsiToWin32 object. - return self.stream.wrapped is sys.stdout - - return self.stream is sys.stdout - - def should_color(self): - # Don't colorize things if we do not have colorama or if told not to - if not colorama or self._no_color: - return False - - real_stream = ( - self.stream if not isinstance(self.stream, colorama.AnsiToWin32) - else self.stream.wrapped - ) - - # If the stream is a tty we should color it - if hasattr(real_stream, "isatty") and real_stream.isatty(): - return True - - # If we have an ANSI term we should color it - if os.environ.get("TERM") == "ANSI": - return True - - # If anything else we should not color it - return False - - def format(self, record): - msg = logging.StreamHandler.format(self, record) - - if self.should_color(): - for level, color in self.COLORS: - if record.levelno >= level: - msg = color(msg) - break - - return msg - - # The logging module says handleError() can be customized. - def handleError(self, record): - exc_class, exc = sys.exc_info()[:2] - # If a broken pipe occurred while calling write() or flush() on the - # stdout stream in logging's Handler.emit(), then raise our special - # exception so we can handle it in main() instead of logging the - # broken pipe error and continuing. - if (exc_class and self._using_stdout() and - _is_broken_pipe_error(exc_class, exc)): - raise BrokenStdoutLoggingError() - - return super(ColorizedStreamHandler, self).handleError(record) - - -class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): - - def _open(self): - ensure_dir(os.path.dirname(self.baseFilename)) - return logging.handlers.RotatingFileHandler._open(self) - - -class MaxLevelFilter(Filter): - - def __init__(self, level): - self.level = level - - def filter(self, record): - return record.levelno < self.level - - -class ExcludeLoggerFilter(Filter): - - """ - A logging Filter that excludes records from a logger (or its children). - """ - - def filter(self, record): - # The base Filter class allows only records from a logger (or its - # children). - return not super(ExcludeLoggerFilter, self).filter(record) - - -def setup_logging(verbosity, no_color, user_log_file): - """Configures and sets up all of the logging - - Returns the requested logging level, as its integer value. - """ - - # Determine the level to be logging at. - if verbosity >= 1: - level = "DEBUG" - elif verbosity == -1: - level = "WARNING" - elif verbosity == -2: - level = "ERROR" - elif verbosity <= -3: - level = "CRITICAL" - else: - level = "INFO" - - level_number = getattr(logging, level) - - # The "root" logger should match the "console" level *unless* we also need - # to log to a user log file. - include_user_log = user_log_file is not None - if include_user_log: - additional_log_file = user_log_file - root_level = "DEBUG" - else: - additional_log_file = "/dev/null" - root_level = level - - # Disable any logging besides WARNING unless we have DEBUG level logging - # enabled for vendored libraries. - vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" - - # Shorthands for clarity - log_streams = { - "stdout": "ext://sys.stdout", - "stderr": "ext://sys.stderr", - } - handler_classes = { - "stream": "pip._internal.utils.logging.ColorizedStreamHandler", - "file": "pip._internal.utils.logging.BetterRotatingFileHandler", - } - handlers = ["console", "console_errors", "console_subprocess"] + ( - ["user_log"] if include_user_log else [] - ) - - logging.config.dictConfig({ - "version": 1, - "disable_existing_loggers": False, - "filters": { - "exclude_warnings": { - "()": "pip._internal.utils.logging.MaxLevelFilter", - "level": logging.WARNING, - }, - "restrict_to_subprocess": { - "()": "logging.Filter", - "name": subprocess_logger.name, - }, - "exclude_subprocess": { - "()": "pip._internal.utils.logging.ExcludeLoggerFilter", - "name": subprocess_logger.name, - }, - }, - "formatters": { - "indent": { - "()": IndentingFormatter, - "format": "%(message)s", - }, - "indent_with_timestamp": { - "()": IndentingFormatter, - "format": "%(message)s", - "add_timestamp": True, - }, - }, - "handlers": { - "console": { - "level": level, - "class": handler_classes["stream"], - "no_color": no_color, - "stream": log_streams["stdout"], - "filters": ["exclude_subprocess", "exclude_warnings"], - "formatter": "indent", - }, - "console_errors": { - "level": "WARNING", - "class": handler_classes["stream"], - "no_color": no_color, - "stream": log_streams["stderr"], - "filters": ["exclude_subprocess"], - "formatter": "indent", - }, - # A handler responsible for logging to the console messages - # from the "subprocessor" logger. - "console_subprocess": { - "level": level, - "class": handler_classes["stream"], - "no_color": no_color, - "stream": log_streams["stderr"], - "filters": ["restrict_to_subprocess"], - "formatter": "indent", - }, - "user_log": { - "level": "DEBUG", - "class": handler_classes["file"], - "filename": additional_log_file, - "delay": True, - "formatter": "indent_with_timestamp", - }, - }, - "root": { - "level": root_level, - "handlers": handlers, - }, - "loggers": { - "pip._vendor": { - "level": vendored_log_level - } - }, - }) - - return level_number diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/misc.py b/env/lib/python3.8/site-packages/pip/_internal/utils/misc.py deleted file mode 100644 index 0f388ebf..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/misc.py +++ /dev/null @@ -1,927 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import contextlib -import errno -import getpass -import hashlib -import io -import logging -import os -import posixpath -import shutil -import stat -import sys -from collections import deque - -from pip._vendor import pkg_resources -# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import. -from pip._vendor.retrying import retry # type: ignore -from pip._vendor.six import PY2, text_type -from pip._vendor.six.moves import input, map, zip_longest -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote - -from pip import __version__ -from pip._internal.exceptions import CommandError -from pip._internal.locations import ( - get_major_minor_version, - site_packages, - user_site, -) -from pip._internal.utils.compat import ( - WINDOWS, - expanduser, - stdlib_pkgs, - str_to_display, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast -from pip._internal.utils.virtualenv import ( - running_under_virtualenv, - virtualenv_no_global, -) - -if PY2: - from io import BytesIO as StringIO -else: - from io import StringIO - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, AnyStr, Container, Iterable, Iterator, List, Optional, Text, - Tuple, Union, - ) - from pip._vendor.pkg_resources import Distribution - - VersionInfo = Tuple[int, int, int] - - -__all__ = ['rmtree', 'display_path', 'backup_dir', - 'ask', 'splitext', - 'format_size', 'is_installable_dir', - 'normalize_path', - 'renames', 'get_prog', - 'captured_stdout', 'ensure_dir', - 'get_installed_version', 'remove_auth_from_url'] - - -logger = logging.getLogger(__name__) - - -def get_pip_version(): - # type: () -> str - pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..") - pip_pkg_dir = os.path.abspath(pip_pkg_dir) - - return ( - 'pip {} from {} (python {})'.format( - __version__, pip_pkg_dir, get_major_minor_version(), - ) - ) - - -def normalize_version_info(py_version_info): - # type: (Tuple[int, ...]) -> Tuple[int, int, int] - """ - Convert a tuple of ints representing a Python version to one of length - three. - - :param py_version_info: a tuple of ints representing a Python version, - or None to specify no version. The tuple can have any length. - - :return: a tuple of length three if `py_version_info` is non-None. - Otherwise, return `py_version_info` unchanged (i.e. None). - """ - if len(py_version_info) < 3: - py_version_info += (3 - len(py_version_info)) * (0,) - elif len(py_version_info) > 3: - py_version_info = py_version_info[:3] - - return cast('VersionInfo', py_version_info) - - -def ensure_dir(path): - # type: (AnyStr) -> None - """os.path.makedirs without EEXIST.""" - try: - os.makedirs(path) - except OSError as e: - # Windows can raise spurious ENOTEMPTY errors. See #6426. - if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: - raise - - -def get_prog(): - # type: () -> str - try: - prog = os.path.basename(sys.argv[0]) - if prog in ('__main__.py', '-c'): - return "{} -m pip".format(sys.executable) - else: - return prog - except (AttributeError, TypeError, IndexError): - pass - return 'pip' - - -# Retry every half second for up to 3 seconds -@retry(stop_max_delay=3000, wait_fixed=500) -def rmtree(dir, ignore_errors=False): - # type: (str, bool) -> None - shutil.rmtree(dir, ignore_errors=ignore_errors, - onerror=rmtree_errorhandler) - - -def rmtree_errorhandler(func, path, exc_info): - """On Windows, the files in .svn are read-only, so when rmtree() tries to - remove them, an exception is thrown. We catch that here, remove the - read-only attribute, and hopefully continue without problems.""" - try: - has_attr_readonly = not (os.stat(path).st_mode & stat.S_IWRITE) - except (IOError, OSError): - # it's equivalent to os.path.exists - return - - if has_attr_readonly: - # convert to read/write - os.chmod(path, stat.S_IWRITE) - # use the original function to repeat the operation - func(path) - return - else: - raise - - -def path_to_display(path): - # type: (Optional[Union[str, Text]]) -> Optional[Text] - """ - Convert a bytes (or text) path to text (unicode in Python 2) for display - and logging purposes. - - This function should never error out. Also, this function is mainly needed - for Python 2 since in Python 3 str paths are already text. - """ - if path is None: - return None - if isinstance(path, text_type): - return path - # Otherwise, path is a bytes object (str in Python 2). - try: - display_path = path.decode(sys.getfilesystemencoding(), 'strict') - except UnicodeDecodeError: - # Include the full bytes to make troubleshooting easier, even though - # it may not be very human readable. - if PY2: - # Convert the bytes to a readable str representation using - # repr(), and then convert the str to unicode. - # Also, we add the prefix "b" to the repr() return value both - # to make the Python 2 output look like the Python 3 output, and - # to signal to the user that this is a bytes representation. - display_path = str_to_display('b{!r}'.format(path)) - else: - # Silence the "F821 undefined name 'ascii'" flake8 error since - # in Python 3 ascii() is a built-in. - display_path = ascii(path) # noqa: F821 - - return display_path - - -def display_path(path): - # type: (Union[str, Text]) -> str - """Gives the display value for a given path, making it relative to cwd - if possible.""" - path = os.path.normcase(os.path.abspath(path)) - if sys.version_info[0] == 2: - path = path.decode(sys.getfilesystemencoding(), 'replace') - path = path.encode(sys.getdefaultencoding(), 'replace') - if path.startswith(os.getcwd() + os.path.sep): - path = '.' + path[len(os.getcwd()):] - return path - - -def backup_dir(dir, ext='.bak'): - # type: (str, str) -> str - """Figure out the name of a directory to back up the given dir to - (adding .bak, .bak2, etc)""" - n = 1 - extension = ext - while os.path.exists(dir + extension): - n += 1 - extension = ext + str(n) - return dir + extension - - -def ask_path_exists(message, options): - # type: (str, Iterable[str]) -> str - for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): - if action in options: - return action - return ask(message, options) - - -def _check_no_input(message): - # type: (str) -> None - """Raise an error if no input is allowed.""" - if os.environ.get('PIP_NO_INPUT'): - raise Exception( - 'No input was expected ($PIP_NO_INPUT set); question: {}'.format( - message) - ) - - -def ask(message, options): - # type: (str, Iterable[str]) -> str - """Ask the message interactively, with the given possible responses""" - while 1: - _check_no_input(message) - response = input(message) - response = response.strip().lower() - if response not in options: - print( - 'Your response ({!r}) was not one of the expected responses: ' - '{}'.format(response, ', '.join(options)) - ) - else: - return response - - -def ask_input(message): - # type: (str) -> str - """Ask for input interactively.""" - _check_no_input(message) - return input(message) - - -def ask_password(message): - # type: (str) -> str - """Ask for a password interactively.""" - _check_no_input(message) - return getpass.getpass(message) - - -def format_size(bytes): - # type: (float) -> str - if bytes > 1000 * 1000: - return '{:.1f} MB'.format(bytes / 1000.0 / 1000) - elif bytes > 10 * 1000: - return '{} kB'.format(int(bytes / 1000)) - elif bytes > 1000: - return '{:.1f} kB'.format(bytes / 1000.0) - else: - return '{} bytes'.format(int(bytes)) - - -def tabulate(rows): - # type: (Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]] - """Return a list of formatted rows and a list of column sizes. - - For example:: - - >>> tabulate([['foobar', 2000], [0xdeadbeef]]) - (['foobar 2000', '3735928559'], [10, 4]) - """ - rows = [tuple(map(str, row)) for row in rows] - sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue='')] - table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows] - return table, sizes - - -def is_installable_dir(path): - # type: (str) -> bool - """Is path is a directory containing setup.py or pyproject.toml? - """ - if not os.path.isdir(path): - return False - setup_py = os.path.join(path, 'setup.py') - if os.path.isfile(setup_py): - return True - pyproject_toml = os.path.join(path, 'pyproject.toml') - if os.path.isfile(pyproject_toml): - return True - return False - - -def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): - """Yield pieces of data from a file-like object until EOF.""" - while True: - chunk = file.read(size) - if not chunk: - break - yield chunk - - -def normalize_path(path, resolve_symlinks=True): - # type: (str, bool) -> str - """ - Convert a path to its canonical, case-normalized, absolute version. - - """ - path = expanduser(path) - if resolve_symlinks: - path = os.path.realpath(path) - else: - path = os.path.abspath(path) - return os.path.normcase(path) - - -def splitext(path): - # type: (str) -> Tuple[str, str] - """Like os.path.splitext, but take off .tar too""" - base, ext = posixpath.splitext(path) - if base.lower().endswith('.tar'): - ext = base[-4:] + ext - base = base[:-4] - return base, ext - - -def renames(old, new): - # type: (str, str) -> None - """Like os.renames(), but handles renaming across devices.""" - # Implementation borrowed from os.renames(). - head, tail = os.path.split(new) - if head and tail and not os.path.exists(head): - os.makedirs(head) - - shutil.move(old, new) - - head, tail = os.path.split(old) - if head and tail: - try: - os.removedirs(head) - except OSError: - pass - - -def is_local(path): - # type: (str) -> bool - """ - Return True if this is a path pip is allowed to modify. - - If we're in a virtualenv, sys.prefix points to the virtualenv's - prefix; only sys.prefix is considered local. - - If we're not in a virtualenv, in general we can modify anything. - However, if the OS vendor has configured distutils to install - somewhere other than sys.prefix (which could be a subdirectory of - sys.prefix, e.g. /usr/local), we consider sys.prefix itself nonlocal - and the domain of the OS vendor. (In other words, everything _other - than_ sys.prefix is considered local.) - - Caution: this function assumes the head of path has been normalized - with normalize_path. - """ - - path = normalize_path(path) - prefix = normalize_path(sys.prefix) - - if running_under_virtualenv(): - return path.startswith(normalize_path(sys.prefix)) - else: - from pip._internal.locations import distutils_scheme - if path.startswith(prefix): - for local_path in distutils_scheme("").values(): - if path.startswith(normalize_path(local_path)): - return True - return False - else: - return True - - -def dist_is_local(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution object is installed somewhere pip - is allowed to modify. - - """ - return is_local(dist_location(dist)) - - -def dist_in_usersite(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is installed in user site. - """ - return dist_location(dist).startswith(normalize_path(user_site)) - - -def dist_in_site_packages(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is installed in - sysconfig.get_python_lib(). - """ - return dist_location(dist).startswith(normalize_path(site_packages)) - - -def dist_is_editable(dist): - # type: (Distribution) -> bool - """ - Return True if given Distribution is an editable install. - """ - return bool(egg_link_path(dist)) - - -def get_installed_distributions( - local_only=True, # type: bool - skip=stdlib_pkgs, # type: Container[str] - include_editables=True, # type: bool - editables_only=False, # type: bool - user_only=False, # type: bool - paths=None # type: Optional[List[str]] -): - # type: (...) -> List[Distribution] - """ - Return a list of installed Distribution objects. - - If ``local_only`` is True (default), only return installations - local to the current virtualenv, if in a virtualenv. - - ``skip`` argument is an iterable of lower-case project names to - ignore; defaults to stdlib_pkgs - - If ``include_editables`` is False, don't report editables. - - If ``editables_only`` is True , only report editables. - - If ``user_only`` is True , only report installations in the user - site directory. - - If ``paths`` is set, only report the distributions present at the - specified list of locations. - """ - if paths: - working_set = pkg_resources.WorkingSet(paths) - else: - working_set = pkg_resources.working_set - - if local_only: - local_test = dist_is_local - else: - def local_test(d): - return True - - if include_editables: - def editable_test(d): - return True - else: - def editable_test(d): - return not dist_is_editable(d) - - if editables_only: - def editables_only_test(d): - return dist_is_editable(d) - else: - def editables_only_test(d): - return True - - if user_only: - user_test = dist_in_usersite - else: - def user_test(d): - return True - - return [d for d in working_set - if local_test(d) and - d.key not in skip and - editable_test(d) and - editables_only_test(d) and - user_test(d) - ] - - -def egg_link_path(dist): - # type: (Distribution) -> Optional[str] - """ - Return the path for the .egg-link file if it exists, otherwise, None. - - There's 3 scenarios: - 1) not in a virtualenv - try to find in site.USER_SITE, then site_packages - 2) in a no-global virtualenv - try to find in site_packages - 3) in a yes-global virtualenv - try to find in site_packages, then site.USER_SITE - (don't look in global location) - - For #1 and #3, there could be odd cases, where there's an egg-link in 2 - locations. - - This method will just return the first one found. - """ - sites = [] - if running_under_virtualenv(): - sites.append(site_packages) - if not virtualenv_no_global() and user_site: - sites.append(user_site) - else: - if user_site: - sites.append(user_site) - sites.append(site_packages) - - for site in sites: - egglink = os.path.join(site, dist.project_name) + '.egg-link' - if os.path.isfile(egglink): - return egglink - return None - - -def dist_location(dist): - # type: (Distribution) -> str - """ - Get the site-packages location of this distribution. Generally - this is dist.location, except in the case of develop-installed - packages, where dist.location is the source code location, and we - want to know where the egg-link file is. - - The returned location is normalized (in particular, with symlinks removed). - """ - egg_link = egg_link_path(dist) - if egg_link: - return normalize_path(egg_link) - return normalize_path(dist.location) - - -def write_output(msg, *args): - # type: (str, str) -> None - logger.info(msg, *args) - - -class FakeFile(object): - """Wrap a list of lines in an object with readline() to make - ConfigParser happy.""" - def __init__(self, lines): - self._gen = (l for l in lines) - - def readline(self): - try: - try: - return next(self._gen) - except NameError: - return self._gen.next() - except StopIteration: - return '' - - def __iter__(self): - return self._gen - - -class StreamWrapper(StringIO): - - @classmethod - def from_stream(cls, orig_stream): - cls.orig_stream = orig_stream - return cls() - - # compileall.compile_dir() needs stdout.encoding to print to stdout - @property - def encoding(self): - return self.orig_stream.encoding - - -@contextlib.contextmanager -def captured_output(stream_name): - """Return a context manager used by captured_stdout/stdin/stderr - that temporarily replaces the sys stream *stream_name* with a StringIO. - - Taken from Lib/support/__init__.py in the CPython repo. - """ - orig_stdout = getattr(sys, stream_name) - setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) - try: - yield getattr(sys, stream_name) - finally: - setattr(sys, stream_name, orig_stdout) - - -def captured_stdout(): - """Capture the output of sys.stdout: - - with captured_stdout() as stdout: - print('hello') - self.assertEqual(stdout.getvalue(), 'hello\n') - - Taken from Lib/support/__init__.py in the CPython repo. - """ - return captured_output('stdout') - - -def captured_stderr(): - """ - See captured_stdout(). - """ - return captured_output('stderr') - - -class cached_property(object): - """A property that is only computed once per instance and then replaces - itself with an ordinary attribute. Deleting the attribute resets the - property. - - Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 - """ - - def __init__(self, func): - self.__doc__ = getattr(func, '__doc__') - self.func = func - - def __get__(self, obj, cls): - if obj is None: - # We're being accessed from the class itself, not from an object - return self - value = obj.__dict__[self.func.__name__] = self.func(obj) - return value - - -def get_installed_version(dist_name, working_set=None): - """Get the installed version of dist_name avoiding pkg_resources cache""" - # Create a requirement that we'll look for inside of setuptools. - req = pkg_resources.Requirement.parse(dist_name) - - if working_set is None: - # We want to avoid having this cached, so we need to construct a new - # working set each time. - working_set = pkg_resources.WorkingSet() - - # Get the installed distribution from our working set - dist = working_set.find(req) - - # Check to see if we got an installed distribution or not, if we did - # we want to return it's version. - return dist.version if dist else None - - -def consume(iterator): - """Consume an iterable at C speed.""" - deque(iterator, maxlen=0) - - -# Simulates an enum -def enum(*sequential, **named): - enums = dict(zip(sequential, range(len(sequential))), **named) - reverse = {value: key for key, value in enums.items()} - enums['reverse_mapping'] = reverse - return type('Enum', (), enums) - - -def build_netloc(host, port): - # type: (str, Optional[int]) -> str - """ - Build a netloc from a host-port pair - """ - if port is None: - return host - if ':' in host: - # Only wrap host with square brackets when it is IPv6 - host = '[{}]'.format(host) - return '{}:{}'.format(host, port) - - -def build_url_from_netloc(netloc, scheme='https'): - # type: (str, str) -> str - """ - Build a full URL from a netloc. - """ - if netloc.count(':') >= 2 and '@' not in netloc and '[' not in netloc: - # It must be a bare IPv6 address, so wrap it with brackets. - netloc = '[{}]'.format(netloc) - return '{}://{}'.format(scheme, netloc) - - -def parse_netloc(netloc): - # type: (str) -> Tuple[str, Optional[int]] - """ - Return the host-port pair from a netloc. - """ - url = build_url_from_netloc(netloc) - parsed = urllib_parse.urlparse(url) - return parsed.hostname, parsed.port - - -def split_auth_from_netloc(netloc): - """ - Parse out and remove the auth information from a netloc. - - Returns: (netloc, (username, password)). - """ - if '@' not in netloc: - return netloc, (None, None) - - # Split from the right because that's how urllib.parse.urlsplit() - # behaves if more than one @ is present (which can be checked using - # the password attribute of urlsplit()'s return value). - auth, netloc = netloc.rsplit('@', 1) - if ':' in auth: - # Split from the left because that's how urllib.parse.urlsplit() - # behaves if more than one : is present (which again can be checked - # using the password attribute of the return value) - user_pass = auth.split(':', 1) - else: - user_pass = auth, None - - user_pass = tuple( - None if x is None else urllib_unquote(x) for x in user_pass - ) - - return netloc, user_pass - - -def redact_netloc(netloc): - # type: (str) -> str - """ - Replace the sensitive data in a netloc with "****", if it exists. - - For example: - - "user:pass@example.com" returns "user:****@example.com" - - "accesstoken@example.com" returns "****@example.com" - """ - netloc, (user, password) = split_auth_from_netloc(netloc) - if user is None: - return netloc - if password is None: - user = '****' - password = '' - else: - user = urllib_parse.quote(user) - password = ':****' - return '{user}{password}@{netloc}'.format(user=user, - password=password, - netloc=netloc) - - -def _transform_url(url, transform_netloc): - """Transform and replace netloc in a url. - - transform_netloc is a function taking the netloc and returning a - tuple. The first element of this tuple is the new netloc. The - entire tuple is returned. - - Returns a tuple containing the transformed url as item 0 and the - original tuple returned by transform_netloc as item 1. - """ - purl = urllib_parse.urlsplit(url) - netloc_tuple = transform_netloc(purl.netloc) - # stripped url - url_pieces = ( - purl.scheme, netloc_tuple[0], purl.path, purl.query, purl.fragment - ) - surl = urllib_parse.urlunsplit(url_pieces) - return surl, netloc_tuple - - -def _get_netloc(netloc): - return split_auth_from_netloc(netloc) - - -def _redact_netloc(netloc): - return (redact_netloc(netloc),) - - -def split_auth_netloc_from_url(url): - # type: (str) -> Tuple[str, str, Tuple[str, str]] - """ - Parse a url into separate netloc, auth, and url with no auth. - - Returns: (url_without_auth, netloc, (username, password)) - """ - url_without_auth, (netloc, auth) = _transform_url(url, _get_netloc) - return url_without_auth, netloc, auth - - -def remove_auth_from_url(url): - # type: (str) -> str - """Return a copy of url with 'username:password@' removed.""" - # username/pass params are passed to subversion through flags - # and are not recognized in the url. - return _transform_url(url, _get_netloc)[0] - - -def redact_auth_from_url(url): - # type: (str) -> str - """Replace the password in a given url with ****.""" - return _transform_url(url, _redact_netloc)[0] - - -class HiddenText(object): - def __init__( - self, - secret, # type: str - redacted, # type: str - ): - # type: (...) -> None - self.secret = secret - self.redacted = redacted - - def __repr__(self): - # type: (...) -> str - return ''.format(str(self)) - - def __str__(self): - # type: (...) -> str - return self.redacted - - # This is useful for testing. - def __eq__(self, other): - # type: (Any) -> bool - if type(self) != type(other): - return False - - # The string being used for redaction doesn't also have to match, - # just the raw, original string. - return (self.secret == other.secret) - - # We need to provide an explicit __ne__ implementation for Python 2. - # TODO: remove this when we drop PY2 support. - def __ne__(self, other): - # type: (Any) -> bool - return not self == other - - -def hide_value(value): - # type: (str) -> HiddenText - return HiddenText(value, redacted='****') - - -def hide_url(url): - # type: (str) -> HiddenText - redacted = redact_auth_from_url(url) - return HiddenText(url, redacted=redacted) - - -def protect_pip_from_modification_on_windows(modifying_pip): - # type: (bool) -> None - """Protection of pip.exe from modification on Windows - - On Windows, any operation modifying pip should be run as: - python -m pip ... - """ - pip_names = [ - "pip.exe", - "pip{}.exe".format(sys.version_info[0]), - "pip{}.{}.exe".format(*sys.version_info[:2]) - ] - - # See https://github.com/pypa/pip/issues/1299 for more discussion - should_show_use_python_msg = ( - modifying_pip and - WINDOWS and - os.path.basename(sys.argv[0]) in pip_names - ) - - if should_show_use_python_msg: - new_command = [ - sys.executable, "-m", "pip" - ] + sys.argv[1:] - raise CommandError( - 'To modify pip, please run the following command:\n{}' - .format(" ".join(new_command)) - ) - - -def is_console_interactive(): - # type: () -> bool - """Is this console interactive? - """ - return sys.stdin is not None and sys.stdin.isatty() - - -def hash_file(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[Any, int] - """Return (hash, length) for path using hashlib.sha256() - """ - - h = hashlib.sha256() - length = 0 - with open(path, 'rb') as f: - for block in read_chunks(f, size=blocksize): - length += len(block) - h.update(block) - return h, length - - -def is_wheel_installed(): - """ - Return whether the wheel package is installed. - """ - try: - import wheel # noqa: F401 - except ImportError: - return False - - return True - - -def pairwise(iterable): - # type: (Iterable[Any]) -> Iterator[Tuple[Any, Any]] - """ - Return paired elements. - - For example: - s -> (s0, s1), (s2, s3), (s4, s5), ... - """ - iterable = iter(iterable) - return zip_longest(iterable, iterable) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/models.py b/env/lib/python3.8/site-packages/pip/_internal/utils/models.py deleted file mode 100644 index 29e14411..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/models.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Utilities for defining models -""" -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -import operator - - -class KeyBasedCompareMixin(object): - """Provides comparison capabilities that is based on a key - """ - - def __init__(self, key, defining_class): - self._compare_key = key - self._defining_class = defining_class - - def __hash__(self): - return hash(self._compare_key) - - def __lt__(self, other): - return self._compare(other, operator.__lt__) - - def __le__(self, other): - return self._compare(other, operator.__le__) - - def __gt__(self, other): - return self._compare(other, operator.__gt__) - - def __ge__(self, other): - return self._compare(other, operator.__ge__) - - def __eq__(self, other): - return self._compare(other, operator.__eq__) - - def __ne__(self, other): - return self._compare(other, operator.__ne__) - - def _compare(self, other, method): - if not isinstance(other, self._defining_class): - return NotImplemented - - return method(self._compare_key, other._compare_key) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/packaging.py b/env/lib/python3.8/site-packages/pip/_internal/utils/packaging.py deleted file mode 100644 index 68aa86ed..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/packaging.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import absolute_import - -import logging -from email.parser import FeedParser - -from pip._vendor import pkg_resources -from pip._vendor.packaging import specifiers, version - -from pip._internal.exceptions import NoneMetadataError -from pip._internal.utils.misc import display_path -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple - from email.message import Message - from pip._vendor.pkg_resources import Distribution - - -logger = logging.getLogger(__name__) - - -def check_requires_python(requires_python, version_info): - # type: (Optional[str], Tuple[int, ...]) -> bool - """ - Check if the given Python version matches a "Requires-Python" specifier. - - :param version_info: A 3-tuple of ints representing a Python - major-minor-micro version to check (e.g. `sys.version_info[:3]`). - - :return: `True` if the given Python version satisfies the requirement. - Otherwise, return `False`. - - :raises InvalidSpecifier: If `requires_python` has an invalid format. - """ - if requires_python is None: - # The package provides no information - return True - requires_python_specifier = specifiers.SpecifierSet(requires_python) - - python_version = version.parse('.'.join(map(str, version_info))) - return python_version in requires_python_specifier - - -def get_metadata(dist): - # type: (Distribution) -> Message - """ - :raises NoneMetadataError: if the distribution reports `has_metadata()` - True but `get_metadata()` returns None. - """ - metadata_name = 'METADATA' - if (isinstance(dist, pkg_resources.DistInfoDistribution) and - dist.has_metadata(metadata_name)): - metadata = dist.get_metadata(metadata_name) - elif dist.has_metadata('PKG-INFO'): - metadata_name = 'PKG-INFO' - metadata = dist.get_metadata(metadata_name) - else: - logger.warning("No metadata found in %s", display_path(dist.location)) - metadata = '' - - if metadata is None: - raise NoneMetadataError(dist, metadata_name) - - feed_parser = FeedParser() - # The following line errors out if with a "NoneType" TypeError if - # passed metadata=None. - feed_parser.feed(metadata) - return feed_parser.close() - - -def get_requires_python(dist): - # type: (pkg_resources.Distribution) -> Optional[str] - """ - Return the "Requires-Python" metadata for a distribution, or None - if not present. - """ - pkg_info_dict = get_metadata(dist) - requires_python = pkg_info_dict.get('Requires-Python') - - if requires_python is not None: - # Convert to a str to satisfy the type checker, since requires_python - # can be a Header object. - requires_python = str(requires_python) - - return requires_python - - -def get_installer(dist): - # type: (Distribution) -> str - if dist.has_metadata('INSTALLER'): - for line in dist.get_metadata_lines('INSTALLER'): - if line.strip(): - return line.strip() - return '' diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/pkg_resources.py b/env/lib/python3.8/site-packages/pip/_internal/utils/pkg_resources.py deleted file mode 100644 index 0bc129ac..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/pkg_resources.py +++ /dev/null @@ -1,44 +0,0 @@ -from pip._vendor.pkg_resources import yield_lines -from pip._vendor.six import ensure_str - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Dict, Iterable, List - - -class DictMetadata(object): - """IMetadataProvider that reads metadata files from a dictionary. - """ - def __init__(self, metadata): - # type: (Dict[str, bytes]) -> None - self._metadata = metadata - - def has_metadata(self, name): - # type: (str) -> bool - return name in self._metadata - - def get_metadata(self, name): - # type: (str) -> str - try: - return ensure_str(self._metadata[name]) - except UnicodeDecodeError as e: - # Mirrors handling done in pkg_resources.NullProvider. - e.reason += " in {} file".format(name) - raise - - def get_metadata_lines(self, name): - # type: (str) -> Iterable[str] - return yield_lines(self.get_metadata(name)) - - def metadata_isdir(self, name): - # type: (str) -> bool - return False - - def metadata_listdir(self, name): - # type: (str) -> List[str] - return [] - - def run_script(self, script_name, namespace): - # type: (str, str) -> None - pass diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py b/env/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py deleted file mode 100644 index 2a664b00..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py +++ /dev/null @@ -1,181 +0,0 @@ -import sys - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Sequence - -# Shim to wrap setup.py invocation with setuptools -# -# We set sys.argv[0] to the path to the underlying setup.py file so -# setuptools / distutils don't take the path to the setup.py to be "-c" when -# invoking via the shim. This avoids e.g. the following manifest_maker -# warning: "warning: manifest_maker: standard file '-c' not found". -_SETUPTOOLS_SHIM = ( - "import sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};" - "f=getattr(tokenize, 'open', open)(__file__);" - "code=f.read().replace('\\r\\n', '\\n');" - "f.close();" - "exec(compile(code, __file__, 'exec'))" -) - - -def make_setuptools_shim_args( - setup_py_path, # type: str - global_options=None, # type: Sequence[str] - no_user_config=False, # type: bool - unbuffered_output=False # type: bool -): - # type: (...) -> List[str] - """ - Get setuptools command arguments with shim wrapped setup file invocation. - - :param setup_py_path: The path to setup.py to be wrapped. - :param global_options: Additional global options. - :param no_user_config: If True, disables personal user configuration. - :param unbuffered_output: If True, adds the unbuffered switch to the - argument list. - """ - args = [sys.executable] - if unbuffered_output: - args += ["-u"] - args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)] - if global_options: - args += global_options - if no_user_config: - args += ["--no-user-cfg"] - return args - - -def make_setuptools_bdist_wheel_args( - setup_py_path, # type: str - global_options, # type: Sequence[str] - build_options, # type: Sequence[str] - destination_dir, # type: str -): - # type: (...) -> List[str] - # NOTE: Eventually, we'd want to also -S to the flags here, when we're - # isolating. Currently, it breaks Python in virtualenvs, because it - # relies on site.py to find parts of the standard library outside the - # virtualenv. - args = make_setuptools_shim_args( - setup_py_path, - global_options=global_options, - unbuffered_output=True - ) - args += ["bdist_wheel", "-d", destination_dir] - args += build_options - return args - - -def make_setuptools_clean_args( - setup_py_path, # type: str - global_options, # type: Sequence[str] -): - # type: (...) -> List[str] - args = make_setuptools_shim_args( - setup_py_path, - global_options=global_options, - unbuffered_output=True - ) - args += ["clean", "--all"] - return args - - -def make_setuptools_develop_args( - setup_py_path, # type: str - global_options, # type: Sequence[str] - install_options, # type: Sequence[str] - no_user_config, # type: bool - prefix, # type: Optional[str] - home, # type: Optional[str] - use_user_site, # type: bool -): - # type: (...) -> List[str] - assert not (use_user_site and prefix) - - args = make_setuptools_shim_args( - setup_py_path, - global_options=global_options, - no_user_config=no_user_config, - ) - - args += ["develop", "--no-deps"] - - args += install_options - - if prefix: - args += ["--prefix", prefix] - if home is not None: - args += ["--home", home] - - if use_user_site: - args += ["--user", "--prefix="] - - return args - - -def make_setuptools_egg_info_args( - setup_py_path, # type: str - egg_info_dir, # type: Optional[str] - no_user_config, # type: bool -): - # type: (...) -> List[str] - args = make_setuptools_shim_args( - setup_py_path, no_user_config=no_user_config - ) - - args += ["egg_info"] - - if egg_info_dir: - args += ["--egg-base", egg_info_dir] - - return args - - -def make_setuptools_install_args( - setup_py_path, # type: str - global_options, # type: Sequence[str] - install_options, # type: Sequence[str] - record_filename, # type: str - root, # type: Optional[str] - prefix, # type: Optional[str] - header_dir, # type: Optional[str] - home, # type: Optional[str] - use_user_site, # type: bool - no_user_config, # type: bool - pycompile # type: bool -): - # type: (...) -> List[str] - assert not (use_user_site and prefix) - assert not (use_user_site and root) - - args = make_setuptools_shim_args( - setup_py_path, - global_options=global_options, - no_user_config=no_user_config, - unbuffered_output=True - ) - args += ["install", "--record", record_filename] - args += ["--single-version-externally-managed"] - - if root is not None: - args += ["--root", root] - if prefix is not None: - args += ["--prefix", prefix] - if home is not None: - args += ["--home", home] - if use_user_site: - args += ["--user", "--prefix="] - - if pycompile: - args += ["--compile"] - else: - args += ["--no-compile"] - - if header_dir: - args += ["--install-headers", header_dir] - - args += install_options - - return args diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py b/env/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py deleted file mode 100644 index 55c82dae..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/subprocess.py +++ /dev/null @@ -1,277 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import logging -import os -import subprocess - -from pip._vendor.six.moves import shlex_quote - -from pip._internal.cli.spinners import SpinnerInterface, open_spinner -from pip._internal.exceptions import InstallationError -from pip._internal.utils.compat import console_to_str, str_to_display -from pip._internal.utils.logging import subprocess_logger -from pip._internal.utils.misc import HiddenText, path_to_display -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Callable, Iterable, List, Mapping, Optional, Text, Union, - ) - - CommandArgs = List[Union[str, HiddenText]] - - -LOG_DIVIDER = '----------------------------------------' - - -def make_command(*args): - # type: (Union[str, HiddenText, CommandArgs]) -> CommandArgs - """ - Create a CommandArgs object. - """ - command_args = [] # type: CommandArgs - for arg in args: - # Check for list instead of CommandArgs since CommandArgs is - # only known during type-checking. - if isinstance(arg, list): - command_args.extend(arg) - else: - # Otherwise, arg is str or HiddenText. - command_args.append(arg) - - return command_args - - -def format_command_args(args): - # type: (Union[List[str], CommandArgs]) -> str - """ - Format command arguments for display. - """ - # For HiddenText arguments, display the redacted form by calling str(). - # Also, we don't apply str() to arguments that aren't HiddenText since - # this can trigger a UnicodeDecodeError in Python 2 if the argument - # has type unicode and includes a non-ascii character. (The type - # checker doesn't ensure the annotations are correct in all cases.) - return ' '.join( - shlex_quote(str(arg)) if isinstance(arg, HiddenText) - else shlex_quote(arg) for arg in args - ) - - -def reveal_command_args(args): - # type: (Union[List[str], CommandArgs]) -> List[str] - """ - Return the arguments in their raw, unredacted form. - """ - return [ - arg.secret if isinstance(arg, HiddenText) else arg for arg in args - ] - - -def make_subprocess_output_error( - cmd_args, # type: Union[List[str], CommandArgs] - cwd, # type: Optional[str] - lines, # type: List[Text] - exit_status, # type: int -): - # type: (...) -> Text - """ - Create and return the error message to use to log a subprocess error - with command output. - - :param lines: A list of lines, each ending with a newline. - """ - command = format_command_args(cmd_args) - # Convert `command` and `cwd` to text (unicode in Python 2) so we can use - # them as arguments in the unicode format string below. This avoids - # "UnicodeDecodeError: 'ascii' codec can't decode byte ..." in Python 2 - # if either contains a non-ascii character. - command_display = str_to_display(command, desc='command bytes') - cwd_display = path_to_display(cwd) - - # We know the joined output value ends in a newline. - output = ''.join(lines) - msg = ( - # Use a unicode string to avoid "UnicodeEncodeError: 'ascii' - # codec can't encode character ..." in Python 2 when a format - # argument (e.g. `output`) has a non-ascii character. - u'Command errored out with exit status {exit_status}:\n' - ' command: {command_display}\n' - ' cwd: {cwd_display}\n' - 'Complete output ({line_count} lines):\n{output}{divider}' - ).format( - exit_status=exit_status, - command_display=command_display, - cwd_display=cwd_display, - line_count=len(lines), - output=output, - divider=LOG_DIVIDER, - ) - return msg - - -def call_subprocess( - cmd, # type: Union[List[str], CommandArgs] - show_stdout=False, # type: bool - cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] - extra_environ=None, # type: Optional[Mapping[str, Any]] - unset_environ=None, # type: Optional[Iterable[str]] - spinner=None, # type: Optional[SpinnerInterface] - log_failed_cmd=True # type: Optional[bool] -): - # type: (...) -> Text - """ - Args: - show_stdout: if true, use INFO to log the subprocess's stderr and - stdout streams. Otherwise, use DEBUG. Defaults to False. - extra_ok_returncodes: an iterable of integer return codes that are - acceptable, in addition to 0. Defaults to None, which means []. - unset_environ: an iterable of environment variable names to unset - prior to calling subprocess.Popen(). - log_failed_cmd: if false, failed commands are not logged, only raised. - """ - if extra_ok_returncodes is None: - extra_ok_returncodes = [] - if unset_environ is None: - unset_environ = [] - # Most places in pip use show_stdout=False. What this means is-- - # - # - We connect the child's output (combined stderr and stdout) to a - # single pipe, which we read. - # - We log this output to stderr at DEBUG level as it is received. - # - If DEBUG logging isn't enabled (e.g. if --verbose logging wasn't - # requested), then we show a spinner so the user can still see the - # subprocess is in progress. - # - If the subprocess exits with an error, we log the output to stderr - # at ERROR level if it hasn't already been displayed to the console - # (e.g. if --verbose logging wasn't enabled). This way we don't log - # the output to the console twice. - # - # If show_stdout=True, then the above is still done, but with DEBUG - # replaced by INFO. - if show_stdout: - # Then log the subprocess output at INFO level. - log_subprocess = subprocess_logger.info - used_level = logging.INFO - else: - # Then log the subprocess output using DEBUG. This also ensures - # it will be logged to the log file (aka user_log), if enabled. - log_subprocess = subprocess_logger.debug - used_level = logging.DEBUG - - # Whether the subprocess will be visible in the console. - showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level - - # Only use the spinner if we're not showing the subprocess output - # and we have a spinner. - use_spinner = not showing_subprocess and spinner is not None - - if command_desc is None: - command_desc = format_command_args(cmd) - - log_subprocess("Running command %s", command_desc) - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - for name in unset_environ: - env.pop(name, None) - try: - proc = subprocess.Popen( - # Convert HiddenText objects to the underlying str. - reveal_command_args(cmd), - stderr=subprocess.STDOUT, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, cwd=cwd, env=env, - ) - proc.stdin.close() - except Exception as exc: - if log_failed_cmd: - subprocess_logger.critical( - "Error %s while executing command %s", exc, command_desc, - ) - raise - all_output = [] - while True: - # The "line" value is a unicode string in Python 2. - line = console_to_str(proc.stdout.readline()) - if not line: - break - line = line.rstrip() - all_output.append(line + '\n') - - # Show the line immediately. - log_subprocess(line) - # Update the spinner. - if use_spinner: - spinner.spin() - try: - proc.wait() - finally: - if proc.stdout: - proc.stdout.close() - proc_had_error = ( - proc.returncode and proc.returncode not in extra_ok_returncodes - ) - if use_spinner: - if proc_had_error: - spinner.finish("error") - else: - spinner.finish("done") - if proc_had_error: - if on_returncode == 'raise': - if not showing_subprocess and log_failed_cmd: - # Then the subprocess streams haven't been logged to the - # console yet. - msg = make_subprocess_output_error( - cmd_args=cmd, - cwd=cwd, - lines=all_output, - exit_status=proc.returncode, - ) - subprocess_logger.error(msg) - exc_msg = ( - 'Command errored out with exit status {}: {} ' - 'Check the logs for full command output.' - ).format(proc.returncode, command_desc) - raise InstallationError(exc_msg) - elif on_returncode == 'warn': - subprocess_logger.warning( - 'Command "{}" had error code {} in {}'.format( - command_desc, proc.returncode, cwd) - ) - elif on_returncode == 'ignore': - pass - else: - raise ValueError('Invalid value: on_returncode={!r}'.format( - on_returncode)) - return ''.join(all_output) - - -def runner_with_spinner_message(message): - # type: (str) -> Callable[..., None] - """Provide a subprocess_runner that shows a spinner message. - - Intended for use with for pep517's Pep517HookCaller. Thus, the runner has - an API that matches what's expected by Pep517HookCaller.subprocess_runner. - """ - - def runner( - cmd, # type: List[str] - cwd=None, # type: Optional[str] - extra_environ=None # type: Optional[Mapping[str, Any]] - ): - # type: (...) -> None - with open_spinner(message) as spinner: - call_subprocess( - cmd, - cwd=cwd, - extra_environ=extra_environ, - spinner=spinner, - ) - - return runner diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py b/env/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py deleted file mode 100644 index 201ba6d9..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py +++ /dev/null @@ -1,271 +0,0 @@ -from __future__ import absolute_import - -import errno -import itertools -import logging -import os.path -import tempfile -from contextlib import contextmanager - -from pip._vendor.contextlib2 import ExitStack - -from pip._internal.utils.misc import enum, rmtree -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Dict, Iterator, Optional, TypeVar, Union - - _T = TypeVar('_T', bound='TempDirectory') - - -logger = logging.getLogger(__name__) - - -# Kinds of temporary directories. Only needed for ones that are -# globally-managed. -tempdir_kinds = enum( - BUILD_ENV="build-env", - EPHEM_WHEEL_CACHE="ephem-wheel-cache", - REQ_BUILD="req-build", -) - - -_tempdir_manager = None # type: Optional[ExitStack] - - -@contextmanager -def global_tempdir_manager(): - # type: () -> Iterator[None] - global _tempdir_manager - with ExitStack() as stack: - old_tempdir_manager, _tempdir_manager = _tempdir_manager, stack - try: - yield - finally: - _tempdir_manager = old_tempdir_manager - - -class TempDirectoryTypeRegistry(object): - """Manages temp directory behavior - """ - - def __init__(self): - # type: () -> None - self._should_delete = {} # type: Dict[str, bool] - - def set_delete(self, kind, value): - # type: (str, bool) -> None - """Indicate whether a TempDirectory of the given kind should be - auto-deleted. - """ - self._should_delete[kind] = value - - def get_delete(self, kind): - # type: (str) -> bool - """Get configured auto-delete flag for a given TempDirectory type, - default True. - """ - return self._should_delete.get(kind, True) - - -_tempdir_registry = None # type: Optional[TempDirectoryTypeRegistry] - - -@contextmanager -def tempdir_registry(): - # type: () -> Iterator[TempDirectoryTypeRegistry] - """Provides a scoped global tempdir registry that can be used to dictate - whether directories should be deleted. - """ - global _tempdir_registry - old_tempdir_registry = _tempdir_registry - _tempdir_registry = TempDirectoryTypeRegistry() - try: - yield _tempdir_registry - finally: - _tempdir_registry = old_tempdir_registry - - -class _Default(object): - pass - - -_default = _Default() - - -class TempDirectory(object): - """Helper class that owns and cleans up a temporary directory. - - This class can be used as a context manager or as an OO representation of a - temporary directory. - - Attributes: - path - Location to the created temporary directory - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - Methods: - cleanup() - Deletes the temporary directory - - When used as a context manager, if the delete attribute is True, on - exiting the context the temporary directory is deleted. - """ - - def __init__( - self, - path=None, # type: Optional[str] - delete=_default, # type: Union[bool, None, _Default] - kind="temp", # type: str - globally_managed=False, # type: bool - ): - super(TempDirectory, self).__init__() - - if delete is _default: - if path is not None: - # If we were given an explicit directory, resolve delete option - # now. - delete = False - else: - # Otherwise, we wait until cleanup and see what - # tempdir_registry says. - delete = None - - if path is None: - path = self._create(kind) - - self._path = path - self._deleted = False - self.delete = delete - self.kind = kind - - if globally_managed: - assert _tempdir_manager is not None - _tempdir_manager.enter_context(self) - - @property - def path(self): - # type: () -> str - assert not self._deleted, ( - "Attempted to access deleted path: {}".format(self._path) - ) - return self._path - - def __repr__(self): - # type: () -> str - return "<{} {!r}>".format(self.__class__.__name__, self.path) - - def __enter__(self): - # type: (_T) -> _T - return self - - def __exit__(self, exc, value, tb): - # type: (Any, Any, Any) -> None - if self.delete is not None: - delete = self.delete - elif _tempdir_registry: - delete = _tempdir_registry.get_delete(self.kind) - else: - delete = True - - if delete: - self.cleanup() - - def _create(self, kind): - # type: (str) -> str - """Create a temporary directory and store its path in self.path - """ - # We realpath here because some systems have their default tmpdir - # symlinked to another directory. This tends to confuse build - # scripts, so we canonicalize the path by traversing potential - # symlinks here. - path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(kind)) - ) - logger.debug("Created temporary directory: {}".format(path)) - return path - - def cleanup(self): - # type: () -> None - """Remove the temporary directory created and reset state - """ - self._deleted = True - if os.path.exists(self._path): - rmtree(self._path) - - -class AdjacentTempDirectory(TempDirectory): - """Helper class that creates a temporary directory adjacent to a real one. - - Attributes: - original - The original directory to create a temp directory for. - path - After calling create() or entering, contains the full - path to the temporary directory. - delete - Whether the directory should be deleted when exiting - (when used as a contextmanager) - - """ - # The characters that may be used to name the temp directory - # We always prepend a ~ and then rotate through these until - # a usable name is found. - # pkg_resources raises a different error for .dist-info folder - # with leading '-' and invalid metadata - LEADING_CHARS = "-~.=%0123456789" - - def __init__(self, original, delete=None): - # type: (str, Optional[bool]) -> None - self.original = original.rstrip('/\\') - super(AdjacentTempDirectory, self).__init__(delete=delete) - - @classmethod - def _generate_names(cls, name): - # type: (str) -> Iterator[str] - """Generates a series of temporary names. - - The algorithm replaces the leading characters in the name - with ones that are valid filesystem characters, but are not - valid package names (for both Python and pip definitions of - package). - """ - for i in range(1, len(name)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i - 1): - new_name = '~' + ''.join(candidate) + name[i:] - if new_name != name: - yield new_name - - # If we make it this far, we will have to make a longer name - for i in range(len(cls.LEADING_CHARS)): - for candidate in itertools.combinations_with_replacement( - cls.LEADING_CHARS, i): - new_name = '~' + ''.join(candidate) + name - if new_name != name: - yield new_name - - def _create(self, kind): - # type: (str) -> str - root, name = os.path.split(self.original) - for candidate in self._generate_names(name): - path = os.path.join(root, candidate) - try: - os.mkdir(path) - except OSError as ex: - # Continue if the name exists already - if ex.errno != errno.EEXIST: - raise - else: - path = os.path.realpath(path) - break - else: - # Final fallback on the default behavior. - path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(kind)) - ) - - logger.debug("Created temporary directory: {}".format(path)) - return path diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/typing.py b/env/lib/python3.8/site-packages/pip/_internal/utils/typing.py deleted file mode 100644 index 8505a29b..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/typing.py +++ /dev/null @@ -1,38 +0,0 @@ -"""For neatly implementing static typing in pip. - -`mypy` - the static type analysis tool we use - uses the `typing` module, which -provides core functionality fundamental to mypy's functioning. - -Generally, `typing` would be imported at runtime and used in that fashion - -it acts as a no-op at runtime and does not have any run-time overhead by -design. - -As it turns out, `typing` is not vendorable - it uses separate sources for -Python 2/Python 3. Thus, this codebase can not expect it to be present. -To work around this, mypy allows the typing import to be behind a False-y -optional to prevent it from running at runtime and type-comments can be used -to remove the need for the types to be accessible directly during runtime. - -This module provides the False-y guard in a nicely named fashion so that a -curious maintainer can reach here to read this. - -In pip, all static-typing related imports should be guarded as follows: - - from pip._internal.utils.typing import MYPY_CHECK_RUNNING - - if MYPY_CHECK_RUNNING: - from typing import ... - -Ref: https://github.com/python/mypy/issues/3216 -""" - -MYPY_CHECK_RUNNING = False - - -if MYPY_CHECK_RUNNING: - from typing import cast -else: - # typing's cast() is needed at runtime, but we don't want to import typing. - # Thus, we use a dummy no-op version, which we tell mypy to ignore. - def cast(type_, value): # type: ignore - return value diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/unpacking.py b/env/lib/python3.8/site-packages/pip/_internal/utils/unpacking.py deleted file mode 100644 index 7252dc21..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/unpacking.py +++ /dev/null @@ -1,272 +0,0 @@ -"""Utilities related archives. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os -import shutil -import stat -import tarfile -import zipfile - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.filetypes import ( - BZ2_EXTENSIONS, - TAR_EXTENSIONS, - XZ_EXTENSIONS, - ZIP_EXTENSIONS, -) -from pip._internal.utils.misc import ensure_dir -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterable, List, Optional, Text, Union - - -logger = logging.getLogger(__name__) - - -SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS - -try: - import bz2 # noqa - SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS -except ImportError: - logger.debug('bz2 module is not available') - -try: - # Only for Python 3.3+ - import lzma # noqa - SUPPORTED_EXTENSIONS += XZ_EXTENSIONS -except ImportError: - logger.debug('lzma module is not available') - - -def current_umask(): - """Get the current umask which involves having to set it temporarily.""" - mask = os.umask(0) - os.umask(mask) - return mask - - -def split_leading_dir(path): - # type: (Union[str, Text]) -> List[Union[str, Text]] - path = path.lstrip('/').lstrip('\\') - if ( - '/' in path and ( - ('\\' in path and path.find('/') < path.find('\\')) or - '\\' not in path - ) - ): - return path.split('/', 1) - elif '\\' in path: - return path.split('\\', 1) - else: - return [path, ''] - - -def has_leading_dir(paths): - # type: (Iterable[Union[str, Text]]) -> bool - """Returns true if all the paths have the same leading path name - (i.e., everything is in one subdirectory in an archive)""" - common_prefix = None - for path in paths: - prefix, rest = split_leading_dir(path) - if not prefix: - return False - elif common_prefix is None: - common_prefix = prefix - elif prefix != common_prefix: - return False - return True - - -def is_within_directory(directory, target): - # type: ((Union[str, Text]), (Union[str, Text])) -> bool - """ - Return true if the absolute path of target is within the directory - """ - abs_directory = os.path.abspath(directory) - abs_target = os.path.abspath(target) - - prefix = os.path.commonprefix([abs_directory, abs_target]) - return prefix == abs_directory - - -def unzip_file(filename, location, flatten=True): - # type: (str, str, bool) -> None - """ - Unzip the file (with path `filename`) to the destination `location`. All - files are written based on system defaults and umask (i.e. permissions are - not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - zipfp = open(filename, 'rb') - try: - zip = zipfile.ZipFile(zipfp, allowZip64=True) - leading = has_leading_dir(zip.namelist()) and flatten - for info in zip.infolist(): - name = info.filename - fn = name - if leading: - fn = split_leading_dir(name)[1] - fn = os.path.join(location, fn) - dir = os.path.dirname(fn) - if not is_within_directory(location, fn): - message = ( - 'The zip file ({}) has a file ({}) trying to install ' - 'outside target directory ({})' - ) - raise InstallationError(message.format(filename, fn, location)) - if fn.endswith('/') or fn.endswith('\\'): - # A directory - ensure_dir(fn) - else: - ensure_dir(dir) - # Don't use read() to avoid allocating an arbitrarily large - # chunk of memory for the file's content - fp = zip.open(name) - try: - with open(fn, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - finally: - fp.close() - mode = info.external_attr >> 16 - # if mode and regular file and any execute permissions for - # user/group/world? - if mode and stat.S_ISREG(mode) and mode & 0o111: - # make dest file have execute for user/group/world - # (chmod +x) no-op on windows per python docs - os.chmod(fn, (0o777 - current_umask() | 0o111)) - finally: - zipfp.close() - - -def untar_file(filename, location): - # type: (str, str) -> None - """ - Untar the file (with path `filename`) to the destination `location`. - All files are written based on system defaults and umask (i.e. permissions - are not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): - mode = 'r:gz' - elif filename.lower().endswith(BZ2_EXTENSIONS): - mode = 'r:bz2' - elif filename.lower().endswith(XZ_EXTENSIONS): - mode = 'r:xz' - elif filename.lower().endswith('.tar'): - mode = 'r' - else: - logger.warning( - 'Cannot determine compression type for file %s', filename, - ) - mode = 'r:*' - tar = tarfile.open(filename, mode) - try: - leading = has_leading_dir([ - member.name for member in tar.getmembers() - ]) - for member in tar.getmembers(): - fn = member.name - if leading: - # https://github.com/python/mypy/issues/1174 - fn = split_leading_dir(fn)[1] # type: ignore - path = os.path.join(location, fn) - if not is_within_directory(location, path): - message = ( - 'The tar file ({}) has a file ({}) trying to install ' - 'outside target directory ({})' - ) - raise InstallationError( - message.format(filename, path, location) - ) - if member.isdir(): - ensure_dir(path) - elif member.issym(): - try: - # https://github.com/python/typeshed/issues/2673 - tar._extract_member(member, path) # type: ignore - except Exception as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - else: - try: - fp = tar.extractfile(member) - except (KeyError, AttributeError) as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - ensure_dir(os.path.dirname(path)) - with open(path, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - fp.close() - # Update the timestamp (useful for cython compiled files) - # https://github.com/python/typeshed/issues/2673 - tar.utime(member, path) # type: ignore - # member have any execute permissions for user/group/world? - if member.mode & 0o111: - # make dest file have execute for user/group/world - # no-op on windows per python docs - os.chmod(path, (0o777 - current_umask() | 0o111)) - finally: - tar.close() - - -def unpack_file( - filename, # type: str - location, # type: str - content_type=None, # type: Optional[str] -): - # type: (...) -> None - filename = os.path.realpath(filename) - if ( - content_type == 'application/zip' or - filename.lower().endswith(ZIP_EXTENSIONS) or - zipfile.is_zipfile(filename) - ): - unzip_file( - filename, - location, - flatten=not filename.endswith('.whl') - ) - elif ( - content_type == 'application/x-gzip' or - tarfile.is_tarfile(filename) or - filename.lower().endswith( - TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS - ) - ): - untar_file(filename, location) - else: - # FIXME: handle? - # FIXME: magic signatures? - logger.critical( - 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' - 'cannot detect archive format', - filename, location, content_type, - ) - raise InstallationError( - 'Cannot determine archive format of {}'.format(location) - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/urls.py b/env/lib/python3.8/site-packages/pip/_internal/utils/urls.py deleted file mode 100644 index f37bc8f9..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/urls.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import sys - -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Optional, Text, Union - - -def get_url_scheme(url): - # type: (Union[str, Text]) -> Optional[Text] - if ':' not in url: - return None - return url.split(':', 1)[0].lower() - - -def path_to_url(path): - # type: (Union[str, Text]) -> str - """ - Convert a path to a file: URL. The path will be made absolute and have - quoted path parts. - """ - path = os.path.normpath(os.path.abspath(path)) - url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) - return url - - -def url_to_path(url): - # type: (str) -> str - """ - Convert a file: URL to a path. - """ - assert url.startswith('file:'), ( - "You can only turn file: urls into filenames (not {url!r})" - .format(**locals())) - - _, netloc, path, _, _ = urllib_parse.urlsplit(url) - - if not netloc or netloc == 'localhost': - # According to RFC 8089, same as empty authority. - netloc = '' - elif sys.platform == 'win32': - # If we have a UNC path, prepend UNC share notation. - netloc = '\\\\' + netloc - else: - raise ValueError( - 'non-local file URIs are not supported on this platform: {url!r}' - .format(**locals()) - ) - - path = urllib_request.url2pathname(netloc + path) - return path diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py b/env/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py deleted file mode 100644 index 596a69a7..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py +++ /dev/null @@ -1,116 +0,0 @@ -from __future__ import absolute_import - -import logging -import os -import re -import site -import sys - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional - -logger = logging.getLogger(__name__) -_INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile( - r"include-system-site-packages\s*=\s*(?Ptrue|false)" -) - - -def _running_under_venv(): - # type: () -> bool - """Checks if sys.base_prefix and sys.prefix match. - - This handles PEP 405 compliant virtual environments. - """ - return sys.prefix != getattr(sys, "base_prefix", sys.prefix) - - -def _running_under_regular_virtualenv(): - # type: () -> bool - """Checks if sys.real_prefix is set. - - This handles virtual environments created with pypa's virtualenv. - """ - # pypa/virtualenv case - return hasattr(sys, 'real_prefix') - - -def running_under_virtualenv(): - # type: () -> bool - """Return True if we're running inside a virtualenv, False otherwise. - """ - return _running_under_venv() or _running_under_regular_virtualenv() - - -def _get_pyvenv_cfg_lines(): - # type: () -> Optional[List[str]] - """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines - - Returns None, if it could not read/access the file. - """ - pyvenv_cfg_file = os.path.join(sys.prefix, 'pyvenv.cfg') - try: - with open(pyvenv_cfg_file) as f: - return f.read().splitlines() # avoids trailing newlines - except IOError: - return None - - -def _no_global_under_venv(): - # type: () -> bool - """Check `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion - - PEP 405 specifies that when system site-packages are not supposed to be - visible from a virtual environment, `pyvenv.cfg` must contain the following - line: - - include-system-site-packages = false - - Additionally, log a warning if accessing the file fails. - """ - cfg_lines = _get_pyvenv_cfg_lines() - if cfg_lines is None: - # We're not in a "sane" venv, so assume there is no system - # site-packages access (since that's PEP 405's default state). - logger.warning( - "Could not access 'pyvenv.cfg' despite a virtual environment " - "being active. Assuming global site-packages is not accessible " - "in this environment." - ) - return True - - for line in cfg_lines: - match = _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX.match(line) - if match is not None and match.group('value') == 'false': - return True - return False - - -def _no_global_under_regular_virtualenv(): - # type: () -> bool - """Check if "no-global-site-packages.txt" exists beside site.py - - This mirrors logic in pypa/virtualenv for determining whether system - site-packages are visible in the virtual environment. - """ - site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) - no_global_site_packages_file = os.path.join( - site_mod_dir, 'no-global-site-packages.txt', - ) - return os.path.exists(no_global_site_packages_file) - - -def virtualenv_no_global(): - # type: () -> bool - """Returns a boolean, whether running in venv with no system site-packages. - """ - # PEP 405 compliance needs to be checked first since virtualenv >=20 would - # return True for both checks, but is only able to use the PEP 405 config. - if _running_under_venv(): - return _no_global_under_venv() - - if _running_under_regular_virtualenv(): - return _no_global_under_regular_virtualenv() - - return False diff --git a/env/lib/python3.8/site-packages/pip/_internal/utils/wheel.py b/env/lib/python3.8/site-packages/pip/_internal/utils/wheel.py deleted file mode 100644 index 3ebb7710..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/utils/wheel.py +++ /dev/null @@ -1,225 +0,0 @@ -"""Support functions for working with wheel files. -""" - -from __future__ import absolute_import - -import logging -from email.parser import Parser -from zipfile import ZipFile - -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.pkg_resources import DistInfoDistribution -from pip._vendor.six import PY2, ensure_str - -from pip._internal.exceptions import UnsupportedWheel -from pip._internal.utils.pkg_resources import DictMetadata -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from email.message import Message - from typing import Dict, Tuple - - from pip._vendor.pkg_resources import Distribution - -if PY2: - from zipfile import BadZipfile as BadZipFile -else: - from zipfile import BadZipFile - - -VERSION_COMPATIBLE = (1, 0) - - -logger = logging.getLogger(__name__) - - -class WheelMetadata(DictMetadata): - """Metadata provider that maps metadata decoding exceptions to our - internal exception type. - """ - def __init__(self, metadata, wheel_name): - # type: (Dict[str, bytes], str) -> None - super(WheelMetadata, self).__init__(metadata) - self._wheel_name = wheel_name - - def get_metadata(self, name): - # type: (str) -> str - try: - return super(WheelMetadata, self).get_metadata(name) - except UnicodeDecodeError as e: - # Augment the default error with the origin of the file. - raise UnsupportedWheel( - "Error decoding metadata for {}: {}".format( - self._wheel_name, e - ) - ) - - -def pkg_resources_distribution_for_wheel(wheel_zip, name, location): - # type: (ZipFile, str, str) -> Distribution - """Get a pkg_resources distribution given a wheel. - - :raises UnsupportedWheel: on any errors - """ - info_dir, _ = parse_wheel(wheel_zip, name) - - metadata_files = [ - p for p in wheel_zip.namelist() if p.startswith("{}/".format(info_dir)) - ] - - metadata_text = {} # type: Dict[str, bytes] - for path in metadata_files: - # If a flag is set, namelist entries may be unicode in Python 2. - # We coerce them to native str type to match the types used in the rest - # of the code. This cannot fail because unicode can always be encoded - # with UTF-8. - full_path = ensure_str(path) - _, metadata_name = full_path.split("/", 1) - - try: - metadata_text[metadata_name] = read_wheel_metadata_file( - wheel_zip, full_path - ) - except UnsupportedWheel as e: - raise UnsupportedWheel( - "{} has an invalid wheel, {}".format(name, str(e)) - ) - - metadata = WheelMetadata(metadata_text, location) - - return DistInfoDistribution( - location=location, metadata=metadata, project_name=name - ) - - -def parse_wheel(wheel_zip, name): - # type: (ZipFile, str) -> Tuple[str, Message] - """Extract information from the provided wheel, ensuring it meets basic - standards. - - Returns the name of the .dist-info directory and the parsed WHEEL metadata. - """ - try: - info_dir = wheel_dist_info_dir(wheel_zip, name) - metadata = wheel_metadata(wheel_zip, info_dir) - version = wheel_version(metadata) - except UnsupportedWheel as e: - raise UnsupportedWheel( - "{} has an invalid wheel, {}".format(name, str(e)) - ) - - check_compatibility(version, name) - - return info_dir, metadata - - -def wheel_dist_info_dir(source, name): - # type: (ZipFile, str) -> str - """Returns the name of the contained .dist-info directory. - - Raises AssertionError or UnsupportedWheel if not found, >1 found, or - it doesn't match the provided name. - """ - # Zip file path separators must be / - subdirs = list(set(p.split("/")[0] for p in source.namelist())) - - info_dirs = [s for s in subdirs if s.endswith('.dist-info')] - - if not info_dirs: - raise UnsupportedWheel(".dist-info directory not found") - - if len(info_dirs) > 1: - raise UnsupportedWheel( - "multiple .dist-info directories found: {}".format( - ", ".join(info_dirs) - ) - ) - - info_dir = info_dirs[0] - - info_dir_name = canonicalize_name(info_dir) - canonical_name = canonicalize_name(name) - if not info_dir_name.startswith(canonical_name): - raise UnsupportedWheel( - ".dist-info directory {!r} does not start with {!r}".format( - info_dir, canonical_name - ) - ) - - # Zip file paths can be unicode or str depending on the zip entry flags, - # so normalize it. - return ensure_str(info_dir) - - -def read_wheel_metadata_file(source, path): - # type: (ZipFile, str) -> bytes - try: - return source.read(path) - # BadZipFile for general corruption, KeyError for missing entry, - # and RuntimeError for password-protected files - except (BadZipFile, KeyError, RuntimeError) as e: - raise UnsupportedWheel( - "could not read {!r} file: {!r}".format(path, e) - ) - - -def wheel_metadata(source, dist_info_dir): - # type: (ZipFile, str) -> Message - """Return the WHEEL metadata of an extracted wheel, if possible. - Otherwise, raise UnsupportedWheel. - """ - path = "{}/WHEEL".format(dist_info_dir) - # Zip file path separators must be / - wheel_contents = read_wheel_metadata_file(source, path) - - try: - wheel_text = ensure_str(wheel_contents) - except UnicodeDecodeError as e: - raise UnsupportedWheel("error decoding {!r}: {!r}".format(path, e)) - - # FeedParser (used by Parser) does not raise any exceptions. The returned - # message may have .defects populated, but for backwards-compatibility we - # currently ignore them. - return Parser().parsestr(wheel_text) - - -def wheel_version(wheel_data): - # type: (Message) -> Tuple[int, ...] - """Given WHEEL metadata, return the parsed Wheel-Version. - Otherwise, raise UnsupportedWheel. - """ - version_text = wheel_data["Wheel-Version"] - if version_text is None: - raise UnsupportedWheel("WHEEL is missing Wheel-Version") - - version = version_text.strip() - - try: - return tuple(map(int, version.split('.'))) - except ValueError: - raise UnsupportedWheel("invalid Wheel-Version: {!r}".format(version)) - - -def check_compatibility(version, name): - # type: (Tuple[int, ...], str) -> None - """Raises errors or warns if called with an incompatible Wheel-Version. - - pip should refuse to install a Wheel-Version that's a major series - ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when - installing a version only minor version ahead (e.g 1.2 > 1.1). - - version: a 2-tuple representing a Wheel-Version (Major, Minor) - name: name of wheel or package to raise exception about - - :raises UnsupportedWheel: when an incompatible Wheel-Version is given - """ - if version[0] > VERSION_COMPATIBLE[0]: - raise UnsupportedWheel( - "{}'s Wheel-Version ({}) is not compatible with this version " - "of pip".format(name, '.'.join(map(str, version))) - ) - elif version > VERSION_COMPATIBLE: - logger.warning( - 'Installing from a newer Wheel-Version (%s)', - '.'.join(map(str, version)), - ) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py deleted file mode 100644 index 2a4eb137..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Expose a limited set of classes and functions so callers outside of -# the vcs package don't need to import deeper than `pip._internal.vcs`. -# (The test directory and imports protected by MYPY_CHECK_RUNNING may -# still need to import from a vcs sub-package.) -# Import all vcs modules to register each VCS in the VcsSupport object. -import pip._internal.vcs.bazaar -import pip._internal.vcs.git -import pip._internal.vcs.mercurial -import pip._internal.vcs.subversion # noqa: F401 -from pip._internal.vcs.versioncontrol import ( # noqa: F401 - RemoteNotFoundError, - is_url, - make_vcs_requirement_url, - vcs, -) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 51df6085afc3654134640924b679b6795e1e7069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448 zcmZXQy-ve06os9pP1A}_2&obbtR0#ROh{G50%Hdd63SvZi3L{u6K?FH@&LRGufbz@ zW#Sc>xGoVw%C&rseLne0*Y~s8lwdu)eNZtVPgW<40lrX+KsRDhGl|f7XYs zD|Z}PVYEN*(+*WeTQCyBCqW!!7-WR*Ozk9JC)lk`QPSvl{Q$n(hNl1k diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc deleted file mode 100644 index 03724e644aa90456339c545af14863007d177ad4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3747 zcmZ`++j1Mn5#8Av79ap#B~h}hAQw4-Y?8TO6vc_8ShmVB?Q*14yk%#z#0-g*cCpaR zfD}>S6IJm`k}t>u`KaGWeg8 zea;IQ1V??{T8@u-H#U9>X?iWEE+BH9~6;T`&^|)@w zLEb3l;yFu)d9!H6Elbz(b}=8%TRO@Yip6-bSc;dJBUAwqM{T zPM4YabW4@_NQ)#ZhNaY-m!{pP4o16DH-^c76?Mif+jAV|(+J6vIW#!;*Inc7qjknuVn2tUk zYRsm&2_B4wIUV2lAmdyN9*C!!7;cYr|NdaRG>uQiZpE#7B>w4#Ohk|RD>~uCj5{z3 zgGt=j=UyCeKMuciwiyq2_$-QRBH}e3J#!9OT<3M(c;>_nKF6DQ&+!&-yQ7U$pch=u3Rn(o0`Dz7sD))t60pCmpA$G~U)&j{SA? zCft(gpx5u#8jIU`82_BxtsqjSP0i`+Kz*#dL_J8n%)P>J1}g$2uq?nLkJ zVgOA#$IgMTp?&Dqo%ogZk9{D;>K7crv4a(M7#sw!NjM2k(Bf~7FWv2n-s5br(}7Mp z*VT1JTD`915|01MU3&uXG;q;r95rEH?(7I@{0#9-l5kcTlAK6((RIU08$MY@zC+V% z=qh#0PKkO2x4Jv07*pRCy4OzzV((Yjq*l;5ZUoi1_80!guPwcFz45|SNhj=Q^h9D& zv;MgX0^Wy6LK-@RCb(<8ZW=E_wU^SouSo@aiV#M3z6r>W64E z2+izQ9eYMD@-Avtu5W?RKrSadFyO&E@F6E`2nj1(kc9pwTy&J@lKe&f3|-edukygE z{Jfk$rVSJcs;&ddgrgx(wfGpcvYzEGuoI7~)_OJ+fPo(3@up3Y9%d1_Li^|50ki04 zM;<5ie-F1|mz;ws&bK`qlgA;Fz|D<~u}?uCYQ2Dys$jfw8f(bKNs3%)8cL^9lLq@; zA9l%ArT=eYpQ$6jON45rwETQ_u zJQ@RX8_ssfL}U{0z@4~cs^29 zo$)*}7P8#Q#0yFd$jO96XmOZlI?o0|ApvTc4dpGG5A3{INivmC%%VUy3$K#W2{26X zlW!BZ51k=Q(lLfTH9qm4cdIs8QHr8O6$bV%uy2apC5GUJ@YY~$SYrXd@r6_Nc(vz@ zCCKGYEO8Bk|7QvAUnZRenGF2P*IAa8tmD(2U@x+_%w z(2=Nr8c9-=e3TR2OcFY!T9KRddWtrWu4$>w&GsVVqjA(SmzOcOZOS+5YfUvfzi z&89Z_6QU?E%A0i1oUN3mTm({ipSq8zqflg8(_*S8@;pgSUDg7;Lwr=aQJPh6p`(mo ze?hb6vW6GUNA1Xu0++QTj9X}-%j}-+HM-{ZNRK40DJi&_8YMC0Jb4|X_$q3%^<)>t zUMbgA_H?}{cZFJqAEP9cWKc;t#H?DrSq-;7(pj$7i%j*ZG)VqxuDy;&jkboe>K9h2T4l0=l=U;ib7p+%?ZoZXLNa((Jcz3QKdtdr36kI;nEbLVJ=+*!7$qq;*< znQiKD`rp}{EKKWmZ{bl~q?|m8w+v4`iXKvhtnV0QiudML?l( z`@XvGx#xW6JLl@-i3vx+=fT(i>V5pjit=A{bMRx}=3RWnX;o2}!qiCVsC8APvKDD| zP5$b2L;jj|6Tf<7bqaM`_R*sv%8o1>D3|JGSvI4I&SZVEGgY6G_f|CBIaWW`nW@jn z`$BZQGh3gPWji|2nXAvqaxpsDnXk{wvJ;)^oUWhloT;DboUNbjoU5Nxm0+I#2i~C+ zo$tI-f2HHrUD>yc`CqNSD$5fXccFfv^IH8i^mjHc)-U3EseUQYc3%$`_SE|2z}&5{ zNtE7TQ*8PxrGDj(!j7?-uM{>DoY~RqSA%oA)!^zLNkY4)RE~c~Qmd%hl)oKM+Yp%bfRob}R05{4UFm-R+9Rk0L(_#T zpL#t%X=ipjWP#V`5oRfO{LR2?2sJ+H~* zj>m&u?D05GGJUHd@P77(J$hX~%FO%yUPQ}tRzk*t?)~5ith=Em(?42&8d2M#7j~0?V;zfF*J3M7YQ3k~R20XX!iz!(y6ubh8}vFFE{e*};@Y6% z!4JJNeZ+s`5-4?*DXUXhXz1uN`p~mXeC31RM`57sLPrOX z>7M#f+t#;@fw7^9vkb3;HhrMc{hlUjRFfE}Ge>nyI|VJ+HV0-|fkgGyWloE#SlMxU z3)s7S%~+b6;5OR$MO?C(P)Gy_6E9>QP{oh<95qbSI4mtBtM*_Gn9C4B)Xa3umKhB2 zlc`=-qU8_g&89J1;rpPbMmuP1#{J|SJXFl!qG&U! zr5fs_ZWx+6{ld`Gb0p0l9eHRwNy1~PKEw@Ex7C5N0d#GtOlQV7+O{^(b|L3ImH&L8 zB^pVbDSrhC?&^CAGfyeoTGwFKw#Ev(2Kwr(u!kPZrapV>ww6Hdgd&yVYFdWsxm!8- zxmjUYS_XuaL_2=$iG*QwayK$1Q)}PR8$y;P-tUgEH*)~nJQ0sWAhaF@-OL1J!w!s% zIP7K<6862})D@jqFhy4SWNGc*-49p2kCq?sYp6LY>nYknyxnNvhv*}rP=R!(RYyIo z8OFSt9v|uIfxZoiQ5ZlUk|$}a)YSJ-U@Fs?-qImSNOqtxgP8-BS>G7j`as`R_Y~6I zUC0kIerI4LkRW6%<#!KqB*~?b;|@P-@D9A|Chfp&^f?c@iJNQBRX67DDv-bpn=V@uF@a!_m4ToxogG>XaImD;#9EsLj}^*9O}RUR~-Yt={m0v7U2{f^9J z`I(;0!r5@&i#MV4^g4|g8qVKDYo<3IvlM#X6pQV^XJT=+V(_0*izyNw_V~|G=3qTa z#YE>wWOfucq!Z2zLWazO3iSGbI81VMn`UU6hU*?$4e6~QD^wf@d!;Gz?}eq?nxjr@ z>D*|?4i7s7FXTvy_{vRtfWkoC#m4QaVg_5Ko>aEgL~i3Z>hIpdwkaFhK;Hn!kcp@O zoDFO$v&g{=)RxJL)XJQ1bXECO`Kj_}%9`>3^axv7PTyU6LKH>rAYRQSA1^{85wumb zuYe3UiDi+1BkW4)xFaz=R~IuYkdwf0j7@Ndipt4ZrjsLpsG>4>l4?~S-)3r8t360F ze6svZliS2eGgq+#cF<+glsHk+%*vg1W)T08+lJjE3*t+3p@(F40_NkfkRRC`{sCGa z;hQ6q?x?m_hV2+?8M|V9pE|S?`HLTtK0SFX{eQxZgdlaGwE#C{JdiSsB_u48Z=1Q%d!7d}HmzaW@wm~f&K*P zU0C8(nBY)LD_336ARf2}n$Zf=BuWW2Ai^`A3l>a@F!CsF*Y5<>mrF7^v}Uq*_z&1U z`trx22&DPfobfa_$G^&a`;Nx|Y(@j!DC`C|+%I0`+v%Ldi+purG3H?_>@I$> zot9-i7AbJIdcRVTD#^)A;RXoxX%fMIE-OCqqkfPxY^xb_uv5^aAgMU~Hoe#tx?H5o z9qMk-+?hcW@KaQ~LbXl~rg-^gRv_<;!cjfHjE=v?SI}fiiL_gLVQJ(i;Dh0dXEg`d zLth&<;ArXW2!lpDN*tkK(D31>fM5Db1lmOb2qGN=Q#XrZCV}>X!oVH|#-0XkH=&;< zwee-xgiaa`T(bDv1EZ@kb)b8&6%ZeDVC<-(o>;pD21>L?Xl3l$Ob52LsRwMWm^jiY z0n>I%d&-U>-BXThWt4$xAOhxr=U^P1(!Y#VYb`+dwG~JW9qJ1J%y+xNV|Q&FhPd(i z26VtB&n>m^-pb84-B{}Sc&d>z%Qc%r6Px7FniM_#AF2((j)>I_Jou%D?yK%6m}gpCU@bISh(u?Li9Ufx3zD9ur<6%Ej4i!i<#LB5c=>x!A3n(rQT=G^3wfV zD;{}X{u=5l6IlWN3<|WBP2LnD;Nw7(lLlqBj3^`rkA2?7 zi{xID+$blcglfi;MrY-N%oFypujz!UvtJRzXD@o0ZATfl&-U(Cgp%m5cVgC$0#UJZCM5mH*t+tVZuHpU3wPMiI_0bVNO)J27~%l{{u2)r z6qP8jvRQRjv$RQ&CR?8*O9P>`5ZIApakL@5g~KuQNj;q)$1h*f8`QZ4uHopAPOyKlX;hy z);$iu5)8%~U@o-s9d*;>uVaN;&MI3Z1yic?%&1m!PFa_)eQYoYa^VTdAWTTgkdlJw zjb=b^7{^#r_G)UrS-W1l#wk9L0!b~XDyWQyO?C?*J?yIpAOxuIMij`;<5g4pMu zqbvFTwm;-6G-~_;6nf&b(wI?sL`Ue~JzxCVL;{%(+X!nk25gOrvFpOq^CS-H}&cqP|w1BB7)RiJ*9<2peaa{+TIjsc!3fd#gO5}=3NIXQd-*`-M}o!RHF zqv5NE{5nzDG1y$j4MJn`DP?4oWZr{7r$t@~aPtlP56lRe4{X1=Dw7M(iy$6VnY&r$ zzr+L;ZJ+A{N~CWk3FMi$(kPh6s3Yr?-uN0VZW`SQQ4LxKr3H`_NT>Igk`tXnWP3NZDAe6PMk+{Q|OJ=V9O z!jqCx#7z!RrvH%+zY49V!wIPAFd0CZ0+&t$_Swg9{3z`+8cUI7m?w#TU=aTj3rmYo z<}j%u{L2NNYPA|%oaC5<3YiuQ{t*?-P~d!pU#D^bC7BzbV}gVG0&j}!8D`6{lfzSs zBRi9)N#Rh(A?J14CYi@9kfvdazISxezBzS2W;!_F&}NaX5RU2iis!f_ppZN2Lvvdu zgk_9`V%Yl40?#Nnv{?}UoD>nu(bI4U z0fkW$Cn*h-9SsBuZ~9Q*R=1sPP%HGn@dWkg&iz=QfioyIDH@ybNtR>1`Uqi4_ykZV zlK#32JQWDHHv@N}k2vJrb}SM}YUyr~wu=rD7V^Ms0p|oa78e)xmF#}oPZk8!@lhYS z0z^zf!^cS1kCJxWZ^>BhsY^BY?yV5uK6ORh36hYK7A!^*a{OM8W4@U`#&`4QxB~R9 z6S#Rw62`gGU$4~M_xgwv0|bzG9=hgzK<36X5mbOT*4!0%g@F1J^ubt=OYvJiwBK*S zQy_j~$ebX~<9Xtgnkkh+g4thUX3$y4Dt{kZ^jv-TT)iS;I@KYG)TFi>sR0>XNgcZ8 zubx`@FMkW85boJPRhg9FtEiAUP6To?>zPfWEeh9x)AB4bE93qxG9=muLUWutHiFDS zb-z2zXH$5}{{mAXb=vO*oS&oeEWtRsQKaT!VV;i@ze+hrNTQ|i5mH>4)eRCP4TnaI z=klkS-Q<3&gRF5j6?VfU^dnD1NIk)m6u?C3jWS0{&g(^ek)v&q^aSUVLg0L-=y?r{ z5T2Ktw~TH64$oa7W4?xhQksG5nAbF-Ys6Gl?S=d^K}q0TW?zt-DdTSr6lG3J=dtbb z0O;tl4w<`#na9{nE;3Oz5CO?6`4yFrR-C5D0;mmhr^F$pWm}YQFA&X>Q3t45iS&I) z>$BpR;`7Itl_(jBCM{Lr>EUMtAUF?4DE_FJ{5SZ?g^Dz6D3Tl+C33=R?R%=je3lda z-6R;%gG?DEUN3v=TKC=E1?hz4G}1+)H{Ei`R+C zNhV7o(7|!dZ5_PrXT$91Cqv$50%M4^LNuRA;h?<$Ubm6A=XDR1#NH_GI&j$~I;7a6 z!yJ1x_aal(s!Zr5F;1hmf@m4UmiQQ41H~M9viTlL*(6dLUekvuF|W~K=?CC)QJ#mv zK}5ijZ;?kAm*BdDi);^Kee4p^F*+n4qYl-f193Qi3)9izSgK7pFoD0NCrTrc2YCc+ zd1hUnq35oRSV|rpnk-oFw>YWPfi1O>%j`%qu)sWVU~$OF>9D6v<@_ILklbIX{(HDh zXlq|bLD4AZO-T~z(

    fwLdt8N%C+n42>9-t)?eON`K@vD>!XGm)V|2$l!UI<9WHJ zqFnYoI&{oic!+0Z1vpcQA-UVl;UotDkxc+gfEGb_E97xEn_@xJ??(v*rvx8a8AoYJ z*Z@|yW5zFGKE6m7ibb-LH1lDb42&tkFLPI1Mkfn&%jwdm3mFe5)szg3e@!LA1*!O) zM3hYov7-@0(Fi}J6s0_+C~5m@_zJS4oV!7oCccCxx_!)^!0)WQUO?$8zLWNOyJSzH zbQ%ittH|T#%q>0AMdcon_(`fdOBZR}HUcofE*#=M!j5e*v)|6m@>CPB@1b*)6#M+SxlEYOIofc%jrsICB4wO zkgj%CO@p_@-?82t=DgUssQWa~XRWh_HtXmqe(BikTzKaj=b>rS36q1X!rRr~nY%@>OFk@=* zW+sa;Nx~w|v$uuF1r1=a93FbIo2eW&4l9z^93e9wQv)4^M@;8Br_eN-%caPOmg z!REVfZ@w4Y`gCjS=GHr?oulDFkq1MOv~AV=Jr@$IZ01=Z@Bvg)AACZ|H9~+>?wBXp@+4Wzc3u5vjS~hR<#efh=w8#6J_;# zBYUIYQMeKd#_IodNoM7hE%>fjMzt=!dHs5k4z3U4!TK;8gwcJ@*7y3HC+oi)ZtuUm zy`NCq^&rj)F0wGW4!vAYPmZuL*jI}^UIg2rd7jvqOv5og*N{3MUGpsHL? z0MwlOFj+zmLzEkes2}h08;>nDC;RzcAPbfcVYSg7+iE+)!~RvZ1XMZX3~Ejcv#BFF z%8@+jD(_?^@f3~l3V2t*VlmT?xPS(65yeY*WD|v9H_Vphm{r3vobN`h8N%gmqZ3!4 zz7;&Q8x8A65XSbAacmqog?R+`7+Yhfu*c@1dF&9ZM@~^;02$y~sI5?#0oYUv2g2Cu zv2lq0032#y24Hr#Mi(|=zj4;{`#t}vyebLPt5Pgsxlw(6J$CQ(OKlf2jCLOF5P%>~)6@TqW7C>I^cyxJA&xrV~9Jkv2P{jdJlsjlLyXX!qpD8cbLBgr=&Nl0AW~kGGHrC{4XIip@)qWj&!8}@CDVfq z)y`eYfhg%+pR<4m@K>zs_W{AwPWnE12d7&rjs7GP+auC%;>uK_b(+XqKqf z^`ZQzA7(uc$AI7M#zdw3Y?y9yam^21@gc>El@;N3HdBN-N-b{5OBX z@PiV;$5v?;?_iHGk(+pFkW>rogho<2*Gru<3e_kPD;pWc$p#9eGQ(@MdLFB?^Z$iZ ze|ol4NX>wWK@*F(8<&~e?}xHqg5$sP({*$cVFU&?vYhb=ZsL8k{vcoht$QA@wGyz;hTzTVX=F1@Rf1PN1>SS#!FzJx8RkSTH|2Yj z`x&u4YxMkYlf7^s<{{-U<=U`zOCBzLmS-;%ei|aE-_YAVIT3|P<>(-N&QX@&VssIR ziy&qJ|7;j0`?P=U{r2d}Y}ZeAd_wV*+I6&h6GG`CJ+M6;&n5w)uy*Vt(2!$O{zA(Y zT~?7^tz*<4ScOaSAvuyW`h2RtQ|3XDgUE=!Vt}k(ga6QlXBTjkw2xfPryIx2btdDt zK*{~MJ00uC5^gs2&vS#2yfDcmIC(SI5-;O`We%*w5?3^k$8Aab5)|kKxy}jp6r)s4 zCnlQgycxB~jO1_|NwmCveUAQRta2UG(aEN6HIRBnmuAX1Kj@4q$XbXUk_pK%ioz(s zUJfl{F$D405^G}sJh}uW+05*jP!YHb9_LZzz@Bgu2dv~16IKW|1D*p;VjhDZ-qQ>b z+{HzEzicn-z)ifJ8n}*qG{?Yqj>%-*EpZ!rxS=W{j3q~mCyFR2imLfMLqMVk8NnA- z6GSoShRD+_K#CsSjHXnDark)}m&yYdh1!N0QM%|vj*T}&2k zP<4^#2ia{S}WSGG$mTFbd+SWvTh$6BULL`MtwvtsT$?I zGv!4;XJVE5()C1aQ1KQOS5c@reV|FN-%<4z6?6p=x2U*71)WjNPfj24BsoD~nOe80 z&{&Wjh)7BzZ^YO2-vQsUy}GyHEqYbR9-bPWIv#3kSfY8plxd3l~7V`3@A+-8QCBaLOG zFEQ$wvs0AKaOHu>BQ9lmzq#^#ou)TJeWkqgySn3Eqn(obFV>((2Rv%KLR`Wv>xf cl0sYq7cS3gz@Qt`{|XWyzU;c)`mn+a diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc deleted file mode 100644 index 2a29fb0c8926a498d535b9d08f7ae660fa45c508..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8519 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc deleted file mode 100644 index 5cce8eac774fa99aaded6035e9a3cd1e4b981622..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19646 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 TXS%fCIW=$3-<<#9Lhk None - """ - Export the Bazaar repository at the url to the destination location - """ - # Remove the location to make sure Bazaar can export it correctly - if os.path.exists(location): - rmtree(location) - - url, rev_options = self.get_url_rev_options(url) - self.run_command( - make_command('export', location, url, rev_options.to_args()), - show_stdout=False, - ) - - def fetch_new(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) - cmd_args = ( - make_command('branch', '-q', rev_options.to_args(), url, dest) - ) - self.run_command(cmd_args) - - def switch(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - self.run_command(make_command('switch', url), cwd=dest) - - def update(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - cmd_args = make_command('pull', '-q', rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - @classmethod - def get_url_rev_and_auth(cls, url): - # type: (str) -> Tuple[str, Optional[str], AuthInfo] - # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it - url, rev, user_pass = super(Bazaar, cls).get_url_rev_and_auth(url) - if url.startswith('ssh://'): - url = 'bzr+' + url - return url, rev, user_pass - - @classmethod - def get_remote_url(cls, location): - urls = cls.run_command(['info'], show_stdout=False, cwd=location) - for line in urls.splitlines(): - line = line.strip() - for x in ('checkout of branch: ', - 'parent branch: '): - if line.startswith(x): - repo = line.split(x)[1] - if cls._is_local_repository(repo): - return path_to_url(repo) - return repo - return None - - @classmethod - def get_revision(cls, location): - revision = cls.run_command( - ['revno'], show_stdout=False, cwd=location, - ) - return revision.splitlines()[-1] - - @classmethod - def is_commit_id_equal(cls, dest, name): - """Always assume the versions don't match""" - return False - - -vcs.register(Bazaar) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/git.py b/env/lib/python3.8/site-packages/pip/_internal/vcs/git.py deleted file mode 100644 index e173ec89..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/vcs/git.py +++ /dev/null @@ -1,394 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os.path -import re - -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.misc import display_path, hide_url -from pip._internal.utils.subprocess import make_command -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs.versioncontrol import ( - RemoteNotFoundError, - VersionControl, - find_path_to_setup_from_repo_root, - vcs, -) - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple - from pip._internal.utils.misc import HiddenText - from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions - - -urlsplit = urllib_parse.urlsplit -urlunsplit = urllib_parse.urlunsplit - - -logger = logging.getLogger(__name__) - - -HASH_REGEX = re.compile('^[a-fA-F0-9]{40}$') - - -def looks_like_hash(sha): - return bool(HASH_REGEX.match(sha)) - - -class Git(VersionControl): - name = 'git' - dirname = '.git' - repo_name = 'clone' - schemes = ( - 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', - ) - # Prevent the user's environment variables from interfering with pip: - # https://github.com/pypa/pip/issues/1130 - unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') - default_arg_rev = 'HEAD' - - @staticmethod - def get_base_rev_args(rev): - return [rev] - - def is_immutable_rev_checkout(self, url, dest): - # type: (str, str) -> bool - _, rev_options = self.get_url_rev_options(hide_url(url)) - if not rev_options.rev: - return False - if not self.is_commit_id_equal(dest, rev_options.rev): - # the current commit is different from rev, - # which means rev was something else than a commit hash - return False - # return False in the rare case rev is both a commit hash - # and a tag or a branch; we don't want to cache in that case - # because that branch/tag could point to something else in the future - is_tag_or_branch = bool( - self.get_revision_sha(dest, rev_options.rev)[0] - ) - return not is_tag_or_branch - - def get_git_version(self): - VERSION_PFX = 'git version ' - version = self.run_command(['version'], show_stdout=False) - if version.startswith(VERSION_PFX): - version = version[len(VERSION_PFX):].split()[0] - else: - version = '' - # get first 3 positions of the git version because - # on windows it is x.y.z.windows.t, and this parses as - # LegacyVersion which always smaller than a Version. - version = '.'.join(version.split('.')[:3]) - return parse_version(version) - - @classmethod - def get_current_branch(cls, location): - """ - Return the current branch, or None if HEAD isn't at a branch - (e.g. detached HEAD). - """ - # git-symbolic-ref exits with empty stdout if "HEAD" is a detached - # HEAD rather than a symbolic ref. In addition, the -q causes the - # command to exit with status code 1 instead of 128 in this case - # and to suppress the message to stderr. - args = ['symbolic-ref', '-q', 'HEAD'] - output = cls.run_command( - args, extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, - ) - ref = output.strip() - - if ref.startswith('refs/heads/'): - return ref[len('refs/heads/'):] - - return None - - def export(self, location, url): - # type: (str, HiddenText) -> None - """Export the Git repository at the url to the destination location""" - if not location.endswith('/'): - location = location + '/' - - with TempDirectory(kind="export") as temp_dir: - self.unpack(temp_dir.path, url=url) - self.run_command( - ['checkout-index', '-a', '-f', '--prefix', location], - show_stdout=False, cwd=temp_dir.path - ) - - @classmethod - def get_revision_sha(cls, dest, rev): - """ - Return (sha_or_none, is_branch), where sha_or_none is a commit hash - if the revision names a remote branch or tag, otherwise None. - - Args: - dest: the repository directory. - rev: the revision name. - """ - # Pass rev to pre-filter the list. - output = cls.run_command(['show-ref', rev], cwd=dest, - show_stdout=False, on_returncode='ignore') - refs = {} - for line in output.strip().splitlines(): - try: - sha, ref = line.split() - except ValueError: - # Include the offending line to simplify troubleshooting if - # this error ever occurs. - raise ValueError('unexpected show-ref line: {!r}'.format(line)) - - refs[ref] = sha - - branch_ref = 'refs/remotes/origin/{}'.format(rev) - tag_ref = 'refs/tags/{}'.format(rev) - - sha = refs.get(branch_ref) - if sha is not None: - return (sha, True) - - sha = refs.get(tag_ref) - - return (sha, False) - - @classmethod - def resolve_revision(cls, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> RevOptions - """ - Resolve a revision to a new RevOptions object with the SHA1 of the - branch, tag, or ref if found. - - Args: - rev_options: a RevOptions object. - """ - rev = rev_options.arg_rev - # The arg_rev property's implementation for Git ensures that the - # rev return value is always non-None. - assert rev is not None - - sha, is_branch = cls.get_revision_sha(dest, rev) - - if sha is not None: - rev_options = rev_options.make_new(sha) - rev_options.branch_name = rev if is_branch else None - - return rev_options - - # Do not show a warning for the common case of something that has - # the form of a Git commit hash. - if not looks_like_hash(rev): - logger.warning( - "Did not find branch or tag '%s', assuming revision or ref.", - rev, - ) - - if not rev.startswith('refs/'): - return rev_options - - # If it looks like a ref, we have to fetch it explicitly. - cls.run_command( - make_command('fetch', '-q', url, rev_options.to_args()), - cwd=dest, - ) - # Change the revision to the SHA of the ref we fetched - sha = cls.get_revision(dest, rev='FETCH_HEAD') - rev_options = rev_options.make_new(sha) - - return rev_options - - @classmethod - def is_commit_id_equal(cls, dest, name): - """ - Return whether the current commit hash equals the given name. - - Args: - dest: the repository directory. - name: a string name. - """ - if not name: - # Then avoid an unnecessary subprocess call. - return False - - return cls.get_revision(dest) == name - - def fetch_new(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - rev_display = rev_options.to_display() - logger.info('Cloning %s%s to %s', url, rev_display, display_path(dest)) - self.run_command(make_command('clone', '-q', url, dest)) - - if rev_options.rev: - # Then a specific revision was requested. - rev_options = self.resolve_revision(dest, url, rev_options) - branch_name = getattr(rev_options, 'branch_name', None) - if branch_name is None: - # Only do a checkout if the current commit id doesn't match - # the requested revision. - if not self.is_commit_id_equal(dest, rev_options.rev): - cmd_args = make_command( - 'checkout', '-q', rev_options.to_args(), - ) - self.run_command(cmd_args, cwd=dest) - elif self.get_current_branch(dest) != branch_name: - # Then a specific branch was requested, and that branch - # is not yet checked out. - track_branch = 'origin/{}'.format(branch_name) - cmd_args = [ - 'checkout', '-b', branch_name, '--track', track_branch, - ] - self.run_command(cmd_args, cwd=dest) - - #: repo may contain submodules - self.update_submodules(dest) - - def switch(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - self.run_command( - make_command('config', 'remote.origin.url', url), - cwd=dest, - ) - cmd_args = make_command('checkout', '-q', rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - self.update_submodules(dest) - - def update(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - # First fetch changes from the default remote - if self.get_git_version() >= parse_version('1.9.0'): - # fetch tags in addition to everything else - self.run_command(['fetch', '-q', '--tags'], cwd=dest) - else: - self.run_command(['fetch', '-q'], cwd=dest) - # Then reset to wanted revision (maybe even origin/master) - rev_options = self.resolve_revision(dest, url, rev_options) - cmd_args = make_command('reset', '--hard', '-q', rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - #: update submodules - self.update_submodules(dest) - - @classmethod - def get_remote_url(cls, location): - """ - Return URL of the first remote encountered. - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - # We need to pass 1 for extra_ok_returncodes since the command - # exits with return code 1 if there are no matching lines. - stdout = cls.run_command( - ['config', '--get-regexp', r'remote\..*\.url'], - extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, - ) - remotes = stdout.splitlines() - try: - found_remote = remotes[0] - except IndexError: - raise RemoteNotFoundError - - for remote in remotes: - if remote.startswith('remote.origin.url '): - found_remote = remote - break - url = found_remote.split(' ')[1] - return url.strip() - - @classmethod - def get_revision(cls, location, rev=None): - if rev is None: - rev = 'HEAD' - current_rev = cls.run_command( - ['rev-parse', rev], show_stdout=False, cwd=location, - ) - return current_rev.strip() - - @classmethod - def get_subdirectory(cls, location): - """ - Return the path to setup.py, relative to the repo root. - Return None if setup.py is in the repo root. - """ - # find the repo root - git_dir = cls.run_command( - ['rev-parse', '--git-dir'], - show_stdout=False, cwd=location).strip() - if not os.path.isabs(git_dir): - git_dir = os.path.join(location, git_dir) - repo_root = os.path.abspath(os.path.join(git_dir, '..')) - return find_path_to_setup_from_repo_root(location, repo_root) - - @classmethod - def get_url_rev_and_auth(cls, url): - # type: (str) -> Tuple[str, Optional[str], AuthInfo] - """ - Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. - That's required because although they use SSH they sometimes don't - work with a ssh:// scheme (e.g. GitHub). But we need a scheme for - parsing. Hence we remove it again afterwards and return it as a stub. - """ - # Works around an apparent Git bug - # (see https://article.gmane.org/gmane.comp.version-control.git/146500) - scheme, netloc, path, query, fragment = urlsplit(url) - if scheme.endswith('file'): - initial_slashes = path[:-len(path.lstrip('/'))] - newpath = ( - initial_slashes + - urllib_request.url2pathname(path) - .replace('\\', '/').lstrip('/') - ) - url = urlunsplit((scheme, netloc, newpath, query, fragment)) - after_plus = scheme.find('+') + 1 - url = scheme[:after_plus] + urlunsplit( - (scheme[after_plus:], netloc, newpath, query, fragment), - ) - - if '://' not in url: - assert 'file:' not in url - url = url.replace('git+', 'git+ssh://') - url, rev, user_pass = super(Git, cls).get_url_rev_and_auth(url) - url = url.replace('ssh://', '') - else: - url, rev, user_pass = super(Git, cls).get_url_rev_and_auth(url) - - return url, rev, user_pass - - @classmethod - def update_submodules(cls, location): - if not os.path.exists(os.path.join(location, '.gitmodules')): - return - cls.run_command( - ['submodule', 'update', '--init', '--recursive', '-q'], - cwd=location, - ) - - @classmethod - def get_repository_root(cls, location): - loc = super(Git, cls).get_repository_root(location) - if loc: - return loc - try: - r = cls.run_command( - ['rev-parse', '--show-toplevel'], - cwd=location, - show_stdout=False, - on_returncode='raise', - log_failed_cmd=False, - ) - except BadCommand: - logger.debug("could not determine if %s is under git control " - "because git is not available", location) - return None - except InstallationError: - return None - return os.path.normpath(r.rstrip('\r\n')) - - -vcs.register(Git) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py b/env/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py deleted file mode 100644 index 75e903cc..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py +++ /dev/null @@ -1,161 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os - -from pip._vendor.six.moves import configparser - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.misc import display_path -from pip._internal.utils.subprocess import make_command -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs.versioncontrol import ( - VersionControl, - find_path_to_setup_from_repo_root, - vcs, -) - -if MYPY_CHECK_RUNNING: - from pip._internal.utils.misc import HiddenText - from pip._internal.vcs.versioncontrol import RevOptions - - -logger = logging.getLogger(__name__) - - -class Mercurial(VersionControl): - name = 'hg' - dirname = '.hg' - repo_name = 'clone' - schemes = ( - 'hg', 'hg+file', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http', - ) - - @staticmethod - def get_base_rev_args(rev): - return [rev] - - def export(self, location, url): - # type: (str, HiddenText) -> None - """Export the Hg repository at the url to the destination location""" - with TempDirectory(kind="export") as temp_dir: - self.unpack(temp_dir.path, url=url) - - self.run_command( - ['archive', location], show_stdout=False, cwd=temp_dir.path - ) - - def fetch_new(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - rev_display = rev_options.to_display() - logger.info( - 'Cloning hg %s%s to %s', - url, - rev_display, - display_path(dest), - ) - self.run_command(make_command('clone', '--noupdate', '-q', url, dest)) - self.run_command( - make_command('update', '-q', rev_options.to_args()), - cwd=dest, - ) - - def switch(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - repo_config = os.path.join(dest, self.dirname, 'hgrc') - config = configparser.RawConfigParser() - try: - config.read(repo_config) - config.set('paths', 'default', url.secret) - with open(repo_config, 'w') as config_file: - config.write(config_file) - except (OSError, configparser.NoSectionError) as exc: - logger.warning( - 'Could not switch Mercurial repository to %s: %s', url, exc, - ) - else: - cmd_args = make_command('update', '-q', rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - def update(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - self.run_command(['pull', '-q'], cwd=dest) - cmd_args = make_command('update', '-q', rev_options.to_args()) - self.run_command(cmd_args, cwd=dest) - - @classmethod - def get_remote_url(cls, location): - url = cls.run_command( - ['showconfig', 'paths.default'], - show_stdout=False, cwd=location).strip() - if cls._is_local_repository(url): - url = path_to_url(url) - return url.strip() - - @classmethod - def get_revision(cls, location): - """ - Return the repository-local changeset revision number, as an integer. - """ - current_revision = cls.run_command( - ['parents', '--template={rev}'], - show_stdout=False, cwd=location).strip() - return current_revision - - @classmethod - def get_requirement_revision(cls, location): - """ - Return the changeset identification hash, as a 40-character - hexadecimal string - """ - current_rev_hash = cls.run_command( - ['parents', '--template={node}'], - show_stdout=False, cwd=location).strip() - return current_rev_hash - - @classmethod - def is_commit_id_equal(cls, dest, name): - """Always assume the versions don't match""" - return False - - @classmethod - def get_subdirectory(cls, location): - """ - Return the path to setup.py, relative to the repo root. - Return None if setup.py is in the repo root. - """ - # find the repo root - repo_root = cls.run_command( - ['root'], show_stdout=False, cwd=location).strip() - if not os.path.isabs(repo_root): - repo_root = os.path.abspath(os.path.join(location, repo_root)) - return find_path_to_setup_from_repo_root(location, repo_root) - - @classmethod - def get_repository_root(cls, location): - loc = super(Mercurial, cls).get_repository_root(location) - if loc: - return loc - try: - r = cls.run_command( - ['root'], - cwd=location, - show_stdout=False, - on_returncode='raise', - log_failed_cmd=False, - ) - except BadCommand: - logger.debug("could not determine if %s is under hg control " - "because hg is not available", location) - return None - except InstallationError: - return None - return os.path.normpath(r.rstrip('\r\n')) - - -vcs.register(Mercurial) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py b/env/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py deleted file mode 100644 index 0ec65974..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py +++ /dev/null @@ -1,334 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os -import re - -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - display_path, - is_console_interactive, - rmtree, - split_auth_from_netloc, -) -from pip._internal.utils.subprocess import make_command -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs.versioncontrol import VersionControl, vcs - -_svn_xml_url_re = re.compile('url="([^"]+)"') -_svn_rev_re = re.compile(r'committed-rev="(\d+)"') -_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') -_svn_info_xml_url_re = re.compile(r'(.*)') - - -if MYPY_CHECK_RUNNING: - from typing import Optional, Tuple - from pip._internal.utils.subprocess import CommandArgs - from pip._internal.utils.misc import HiddenText - from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions - - -logger = logging.getLogger(__name__) - - -class Subversion(VersionControl): - name = 'svn' - dirname = '.svn' - repo_name = 'checkout' - schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') - - @classmethod - def should_add_vcs_url_prefix(cls, remote_url): - return True - - @staticmethod - def get_base_rev_args(rev): - return ['-r', rev] - - @classmethod - def get_revision(cls, location): - """ - Return the maximum revision for all files under a given location - """ - # Note: taken from setuptools.command.egg_info - revision = 0 - - for base, dirs, files in os.walk(location): - if cls.dirname not in dirs: - dirs[:] = [] - continue # no sense walking uncontrolled subdirs - dirs.remove(cls.dirname) - entries_fn = os.path.join(base, cls.dirname, 'entries') - if not os.path.exists(entries_fn): - # FIXME: should we warn? - continue - - dirurl, localrev = cls._get_svn_url_rev(base) - - if base == location: - base = dirurl + '/' # save the root url - elif not dirurl or not dirurl.startswith(base): - dirs[:] = [] - continue # not part of the same svn tree, skip it - revision = max(revision, localrev) - return revision - - @classmethod - def get_netloc_and_auth(cls, netloc, scheme): - """ - This override allows the auth information to be passed to svn via the - --username and --password options instead of via the URL. - """ - if scheme == 'ssh': - # The --username and --password options can't be used for - # svn+ssh URLs, so keep the auth information in the URL. - return super(Subversion, cls).get_netloc_and_auth(netloc, scheme) - - return split_auth_from_netloc(netloc) - - @classmethod - def get_url_rev_and_auth(cls, url): - # type: (str) -> Tuple[str, Optional[str], AuthInfo] - # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it - url, rev, user_pass = super(Subversion, cls).get_url_rev_and_auth(url) - if url.startswith('ssh://'): - url = 'svn+' + url - return url, rev, user_pass - - @staticmethod - def make_rev_args(username, password): - # type: (Optional[str], Optional[HiddenText]) -> CommandArgs - extra_args = [] # type: CommandArgs - if username: - extra_args += ['--username', username] - if password: - extra_args += ['--password', password] - - return extra_args - - @classmethod - def get_remote_url(cls, location): - # In cases where the source is in a subdirectory, not alongside - # setup.py we have to look up in the location until we find a real - # setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding setup.py - logger.warning( - "Could not find setup.py for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - - return cls._get_svn_url_rev(location)[0] - - @classmethod - def _get_svn_url_rev(cls, location): - from pip._internal.exceptions import InstallationError - - entries_path = os.path.join(location, cls.dirname, 'entries') - if os.path.exists(entries_path): - with open(entries_path) as f: - data = f.read() - else: # subversion >= 1.7 does not have the 'entries' file - data = '' - - if (data.startswith('8') or - data.startswith('9') or - data.startswith('10')): - data = list(map(str.splitlines, data.split('\n\x0c\n'))) - del data[0][0] # get rid of the '8' - url = data[0][3] - revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] - elif data.startswith('= 1.7 - # Note that using get_remote_call_options is not necessary here - # because `svn info` is being run against a local directory. - # We don't need to worry about making sure interactive mode - # is being used to prompt for passwords, because passwords - # are only potentially needed for remote server requests. - xml = cls.run_command( - ['info', '--xml', location], - show_stdout=False, - ) - url = _svn_info_xml_url_re.search(xml).group(1) - revs = [ - int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) - ] - except InstallationError: - url, revs = None, [] - - if revs: - rev = max(revs) - else: - rev = 0 - - return url, rev - - @classmethod - def is_commit_id_equal(cls, dest, name): - """Always assume the versions don't match""" - return False - - def __init__(self, use_interactive=None): - # type: (bool) -> None - if use_interactive is None: - use_interactive = is_console_interactive() - self.use_interactive = use_interactive - - # This member is used to cache the fetched version of the current - # ``svn`` client. - # Special value definitions: - # None: Not evaluated yet. - # Empty tuple: Could not parse version. - self._vcs_version = None # type: Optional[Tuple[int, ...]] - - super(Subversion, self).__init__() - - def call_vcs_version(self): - # type: () -> Tuple[int, ...] - """Query the version of the currently installed Subversion client. - - :return: A tuple containing the parts of the version information or - ``()`` if the version returned from ``svn`` could not be parsed. - :raises: BadCommand: If ``svn`` is not installed. - """ - # Example versions: - # svn, version 1.10.3 (r1842928) - # compiled Feb 25 2019, 14:20:39 on x86_64-apple-darwin17.0.0 - # svn, version 1.7.14 (r1542130) - # compiled Mar 28 2018, 08:49:13 on x86_64-pc-linux-gnu - version_prefix = 'svn, version ' - version = self.run_command(['--version'], show_stdout=False) - if not version.startswith(version_prefix): - return () - - version = version[len(version_prefix):].split()[0] - version_list = version.split('.') - try: - parsed_version = tuple(map(int, version_list)) - except ValueError: - return () - - return parsed_version - - def get_vcs_version(self): - # type: () -> Tuple[int, ...] - """Return the version of the currently installed Subversion client. - - If the version of the Subversion client has already been queried, - a cached value will be used. - - :return: A tuple containing the parts of the version information or - ``()`` if the version returned from ``svn`` could not be parsed. - :raises: BadCommand: If ``svn`` is not installed. - """ - if self._vcs_version is not None: - # Use cached version, if available. - # If parsing the version failed previously (empty tuple), - # do not attempt to parse it again. - return self._vcs_version - - vcs_version = self.call_vcs_version() - self._vcs_version = vcs_version - return vcs_version - - def get_remote_call_options(self): - # type: () -> CommandArgs - """Return options to be used on calls to Subversion that contact the server. - - These options are applicable for the following ``svn`` subcommands used - in this class. - - - checkout - - export - - switch - - update - - :return: A list of command line arguments to pass to ``svn``. - """ - if not self.use_interactive: - # --non-interactive switch is available since Subversion 0.14.4. - # Subversion < 1.8 runs in interactive mode by default. - return ['--non-interactive'] - - svn_version = self.get_vcs_version() - # By default, Subversion >= 1.8 runs in non-interactive mode if - # stdin is not a TTY. Since that is how pip invokes SVN, in - # call_subprocess(), pip must pass --force-interactive to ensure - # the user can be prompted for a password, if required. - # SVN added the --force-interactive option in SVN 1.8. Since - # e.g. RHEL/CentOS 7, which is supported until 2024, ships with - # SVN 1.7, pip should continue to support SVN 1.7. Therefore, pip - # can't safely add the option if the SVN version is < 1.8 (or unknown). - if svn_version >= (1, 8): - return ['--force-interactive'] - - return [] - - def export(self, location, url): - # type: (str, HiddenText) -> None - """Export the svn repository at the url to the destination location""" - url, rev_options = self.get_url_rev_options(url) - - logger.info('Exporting svn repository %s to %s', url, location) - with indent_log(): - if os.path.exists(location): - # Subversion doesn't like to check out over an existing - # directory --force fixes this, but was only added in svn 1.5 - rmtree(location) - cmd_args = make_command( - 'export', self.get_remote_call_options(), - rev_options.to_args(), url, location, - ) - self.run_command(cmd_args, show_stdout=False) - - def fetch_new(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - rev_display = rev_options.to_display() - logger.info( - 'Checking out %s%s to %s', - url, - rev_display, - display_path(dest), - ) - cmd_args = make_command( - 'checkout', '-q', self.get_remote_call_options(), - rev_options.to_args(), url, dest, - ) - self.run_command(cmd_args) - - def switch(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - cmd_args = make_command( - 'switch', self.get_remote_call_options(), rev_options.to_args(), - url, dest, - ) - self.run_command(cmd_args) - - def update(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - cmd_args = make_command( - 'update', self.get_remote_call_options(), rev_options.to_args(), - dest, - ) - self.run_command(cmd_args) - - -vcs.register(Subversion) diff --git a/env/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py b/env/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py deleted file mode 100644 index 71b4650a..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py +++ /dev/null @@ -1,723 +0,0 @@ -"""Handles all VCS (version control) support""" - -from __future__ import absolute_import - -import errno -import logging -import os -import shutil -import sys - -from pip._vendor import pkg_resources -from pip._vendor.six.moves.urllib import parse as urllib_parse - -from pip._internal.exceptions import BadCommand, InstallationError -from pip._internal.utils.compat import samefile -from pip._internal.utils.misc import ( - ask_path_exists, - backup_dir, - display_path, - hide_url, - hide_value, - rmtree, -) -from pip._internal.utils.subprocess import call_subprocess, make_command -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import get_url_scheme - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Dict, Iterable, Iterator, List, Mapping, Optional, Text, Tuple, - Type, Union - ) - from pip._internal.cli.spinners import SpinnerInterface - from pip._internal.utils.misc import HiddenText - from pip._internal.utils.subprocess import CommandArgs - - AuthInfo = Tuple[Optional[str], Optional[str]] - - -__all__ = ['vcs'] - - -logger = logging.getLogger(__name__) - - -def is_url(name): - # type: (Union[str, Text]) -> bool - """ - Return true if the name looks like a URL. - """ - scheme = get_url_scheme(name) - if scheme is None: - return False - return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes - - -def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): - # type: (str, str, str, Optional[str]) -> str - """ - Return the URL for a VCS requirement. - - Args: - repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). - project_name: the (unescaped) project name. - """ - egg_project_name = pkg_resources.to_filename(project_name) - req = '{}@{}#egg={}'.format(repo_url, rev, egg_project_name) - if subdir: - req += '&subdirectory={}'.format(subdir) - - return req - - -def find_path_to_setup_from_repo_root(location, repo_root): - # type: (str, str) -> Optional[str] - """ - Find the path to `setup.py` by searching up the filesystem from `location`. - Return the path to `setup.py` relative to `repo_root`. - Return None if `setup.py` is in `repo_root` or cannot be found. - """ - # find setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding setup.py - logger.warning( - "Could not find setup.py for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - - if samefile(repo_root, location): - return None - - return os.path.relpath(location, repo_root) - - -class RemoteNotFoundError(Exception): - pass - - -class RevOptions(object): - - """ - Encapsulates a VCS-specific revision to install, along with any VCS - install options. - - Instances of this class should be treated as if immutable. - """ - - def __init__( - self, - vc_class, # type: Type[VersionControl] - rev=None, # type: Optional[str] - extra_args=None, # type: Optional[CommandArgs] - ): - # type: (...) -> None - """ - Args: - vc_class: a VersionControl subclass. - rev: the name of the revision to install. - extra_args: a list of extra options. - """ - if extra_args is None: - extra_args = [] - - self.extra_args = extra_args - self.rev = rev - self.vc_class = vc_class - self.branch_name = None # type: Optional[str] - - def __repr__(self): - # type: () -> str - return ''.format(self.vc_class.name, self.rev) - - @property - def arg_rev(self): - # type: () -> Optional[str] - if self.rev is None: - return self.vc_class.default_arg_rev - - return self.rev - - def to_args(self): - # type: () -> CommandArgs - """ - Return the VCS-specific command arguments. - """ - args = [] # type: CommandArgs - rev = self.arg_rev - if rev is not None: - args += self.vc_class.get_base_rev_args(rev) - args += self.extra_args - - return args - - def to_display(self): - # type: () -> str - if not self.rev: - return '' - - return ' (to revision {})'.format(self.rev) - - def make_new(self, rev): - # type: (str) -> RevOptions - """ - Make a copy of the current instance, but with a new rev. - - Args: - rev: the name of the revision for the new object. - """ - return self.vc_class.make_rev_options(rev, extra_args=self.extra_args) - - -class VcsSupport(object): - _registry = {} # type: Dict[str, VersionControl] - schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] - - def __init__(self): - # type: () -> None - # Register more schemes with urlparse for various version control - # systems - urllib_parse.uses_netloc.extend(self.schemes) - # Python >= 2.7.4, 3.3 doesn't have uses_fragment - if getattr(urllib_parse, 'uses_fragment', None): - urllib_parse.uses_fragment.extend(self.schemes) - super(VcsSupport, self).__init__() - - def __iter__(self): - # type: () -> Iterator[str] - return self._registry.__iter__() - - @property - def backends(self): - # type: () -> List[VersionControl] - return list(self._registry.values()) - - @property - def dirnames(self): - # type: () -> List[str] - return [backend.dirname for backend in self.backends] - - @property - def all_schemes(self): - # type: () -> List[str] - schemes = [] # type: List[str] - for backend in self.backends: - schemes.extend(backend.schemes) - return schemes - - def register(self, cls): - # type: (Type[VersionControl]) -> None - if not hasattr(cls, 'name'): - logger.warning('Cannot register VCS %s', cls.__name__) - return - if cls.name not in self._registry: - self._registry[cls.name] = cls() - logger.debug('Registered VCS backend: %s', cls.name) - - def unregister(self, name): - # type: (str) -> None - if name in self._registry: - del self._registry[name] - - def get_backend_for_dir(self, location): - # type: (str) -> Optional[VersionControl] - """ - Return a VersionControl object if a repository of that type is found - at the given directory. - """ - vcs_backends = {} - for vcs_backend in self._registry.values(): - repo_path = vcs_backend.get_repository_root(location) - if not repo_path: - continue - logger.debug('Determine that %s uses VCS: %s', - location, vcs_backend.name) - vcs_backends[repo_path] = vcs_backend - - if not vcs_backends: - return None - - # Choose the VCS in the inner-most directory. Since all repository - # roots found here would be either `location` or one of its - # parents, the longest path should have the most path components, - # i.e. the backend representing the inner-most repository. - inner_most_repo_path = max(vcs_backends, key=len) - return vcs_backends[inner_most_repo_path] - - def get_backend_for_scheme(self, scheme): - # type: (str) -> Optional[VersionControl] - """ - Return a VersionControl object or None. - """ - for vcs_backend in self._registry.values(): - if scheme in vcs_backend.schemes: - return vcs_backend - return None - - def get_backend(self, name): - # type: (str) -> Optional[VersionControl] - """ - Return a VersionControl object or None. - """ - name = name.lower() - return self._registry.get(name) - - -vcs = VcsSupport() - - -class VersionControl(object): - name = '' - dirname = '' - repo_name = '' - # List of supported schemes for this Version Control - schemes = () # type: Tuple[str, ...] - # Iterable of environment variable names to pass to call_subprocess(). - unset_environ = () # type: Tuple[str, ...] - default_arg_rev = None # type: Optional[str] - - @classmethod - def should_add_vcs_url_prefix(cls, remote_url): - # type: (str) -> bool - """ - Return whether the vcs prefix (e.g. "git+") should be added to a - repository's remote url when used in a requirement. - """ - return not remote_url.lower().startswith('{}:'.format(cls.name)) - - @classmethod - def get_subdirectory(cls, location): - # type: (str) -> Optional[str] - """ - Return the path to setup.py, relative to the repo root. - Return None if setup.py is in the repo root. - """ - return None - - @classmethod - def get_requirement_revision(cls, repo_dir): - # type: (str) -> str - """ - Return the revision string that should be used in a requirement. - """ - return cls.get_revision(repo_dir) - - @classmethod - def get_src_requirement(cls, repo_dir, project_name): - # type: (str, str) -> Optional[str] - """ - Return the requirement string to use to redownload the files - currently at the given repository directory. - - Args: - project_name: the (unescaped) project name. - - The return value has a form similar to the following: - - {repository_url}@{revision}#egg={project_name} - """ - repo_url = cls.get_remote_url(repo_dir) - if repo_url is None: - return None - - if cls.should_add_vcs_url_prefix(repo_url): - repo_url = '{}+{}'.format(cls.name, repo_url) - - revision = cls.get_requirement_revision(repo_dir) - subdir = cls.get_subdirectory(repo_dir) - req = make_vcs_requirement_url(repo_url, revision, project_name, - subdir=subdir) - - return req - - @staticmethod - def get_base_rev_args(rev): - # type: (str) -> List[str] - """ - Return the base revision arguments for a vcs command. - - Args: - rev: the name of a revision to install. Cannot be None. - """ - raise NotImplementedError - - def is_immutable_rev_checkout(self, url, dest): - # type: (str, str) -> bool - """ - Return true if the commit hash checked out at dest matches - the revision in url. - - Always return False, if the VCS does not support immutable commit - hashes. - - This method does not check if there are local uncommitted changes - in dest after checkout, as pip currently has no use case for that. - """ - return False - - @classmethod - def make_rev_options(cls, rev=None, extra_args=None): - # type: (Optional[str], Optional[CommandArgs]) -> RevOptions - """ - Return a RevOptions object. - - Args: - rev: the name of a revision to install. - extra_args: a list of extra options. - """ - return RevOptions(cls, rev, extra_args=extra_args) - - @classmethod - def _is_local_repository(cls, repo): - # type: (str) -> bool - """ - posix absolute paths start with os.path.sep, - win32 ones start with drive (like c:\\folder) - """ - drive, tail = os.path.splitdrive(repo) - return repo.startswith(os.path.sep) or bool(drive) - - def export(self, location, url): - # type: (str, HiddenText) -> None - """ - Export the repository at the url to the destination location - i.e. only download the files, without vcs informations - - :param url: the repository URL starting with a vcs prefix. - """ - raise NotImplementedError - - @classmethod - def get_netloc_and_auth(cls, netloc, scheme): - # type: (str, str) -> Tuple[str, Tuple[Optional[str], Optional[str]]] - """ - Parse the repository URL's netloc, and return the new netloc to use - along with auth information. - - Args: - netloc: the original repository URL netloc. - scheme: the repository URL's scheme without the vcs prefix. - - This is mainly for the Subversion class to override, so that auth - information can be provided via the --username and --password options - instead of through the URL. For other subclasses like Git without - such an option, auth information must stay in the URL. - - Returns: (netloc, (username, password)). - """ - return netloc, (None, None) - - @classmethod - def get_url_rev_and_auth(cls, url): - # type: (str) -> Tuple[str, Optional[str], AuthInfo] - """ - Parse the repository URL to use, and return the URL, revision, - and auth info to use. - - Returns: (url, rev, (username, password)). - """ - scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) - if '+' not in scheme: - raise ValueError( - "Sorry, {!r} is a malformed VCS url. " - "The format is +://, " - "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) - ) - # Remove the vcs prefix. - scheme = scheme.split('+', 1)[1] - netloc, user_pass = cls.get_netloc_and_auth(netloc, scheme) - rev = None - if '@' in path: - path, rev = path.rsplit('@', 1) - if not rev: - raise InstallationError( - "The URL {!r} has an empty revision (after @) " - "which is not supported. Include a revision after @ " - "or remove @ from the URL.".format(url) - ) - url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) - return url, rev, user_pass - - @staticmethod - def make_rev_args(username, password): - # type: (Optional[str], Optional[HiddenText]) -> CommandArgs - """ - Return the RevOptions "extra arguments" to use in obtain(). - """ - return [] - - def get_url_rev_options(self, url): - # type: (HiddenText) -> Tuple[HiddenText, RevOptions] - """ - Return the URL and RevOptions object to use in obtain() and in - some cases export(), as a tuple (url, rev_options). - """ - secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) - username, secret_password = user_pass - password = None # type: Optional[HiddenText] - if secret_password is not None: - password = hide_value(secret_password) - extra_args = self.make_rev_args(username, password) - rev_options = self.make_rev_options(rev, extra_args=extra_args) - - return hide_url(secret_url), rev_options - - @staticmethod - def normalize_url(url): - # type: (str) -> str - """ - Normalize a URL for comparison by unquoting it and removing any - trailing slash. - """ - return urllib_parse.unquote(url).rstrip('/') - - @classmethod - def compare_urls(cls, url1, url2): - # type: (str, str) -> bool - """ - Compare two repo URLs for identity, ignoring incidental differences. - """ - return (cls.normalize_url(url1) == cls.normalize_url(url2)) - - def fetch_new(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - """ - Fetch a revision from a repository, in the case that this is the - first fetch from the repository. - - Args: - dest: the directory to fetch the repository to. - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def switch(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - """ - Switch the repo at ``dest`` to point to ``URL``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - def update(self, dest, url, rev_options): - # type: (str, HiddenText, RevOptions) -> None - """ - Update an already-existing repo to the given ``rev_options``. - - Args: - rev_options: a RevOptions object. - """ - raise NotImplementedError - - @classmethod - def is_commit_id_equal(cls, dest, name): - # type: (str, Optional[str]) -> bool - """ - Return whether the id of the current commit equals the given name. - - Args: - dest: the repository directory. - name: a string name. - """ - raise NotImplementedError - - def obtain(self, dest, url): - # type: (str, HiddenText) -> None - """ - Install or update in editable mode the package represented by this - VersionControl object. - - :param dest: the repository directory in which to install or update. - :param url: the repository URL starting with a vcs prefix. - """ - url, rev_options = self.get_url_rev_options(url) - - if not os.path.exists(dest): - self.fetch_new(dest, url, rev_options) - return - - rev_display = rev_options.to_display() - if self.is_repository_directory(dest): - existing_url = self.get_remote_url(dest) - if self.compare_urls(existing_url, url.secret): - logger.debug( - '%s in %s exists, and has correct URL (%s)', - self.repo_name.title(), - display_path(dest), - url, - ) - if not self.is_commit_id_equal(dest, rev_options.rev): - logger.info( - 'Updating %s %s%s', - display_path(dest), - self.repo_name, - rev_display, - ) - self.update(dest, url, rev_options) - else: - logger.info('Skipping because already up-to-date.') - return - - logger.warning( - '%s %s in %s exists with URL %s', - self.name, - self.repo_name, - display_path(dest), - existing_url, - ) - prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', - ('s', 'i', 'w', 'b')) - else: - logger.warning( - 'Directory %s already exists, and is not a %s %s.', - dest, - self.name, - self.repo_name, - ) - # https://github.com/python/mypy/issues/1174 - prompt = ('(i)gnore, (w)ipe, (b)ackup ', # type: ignore - ('i', 'w', 'b')) - - logger.warning( - 'The plan is to install the %s repository %s', - self.name, - url, - ) - response = ask_path_exists('What to do? {}'.format( - prompt[0]), prompt[1]) - - if response == 'a': - sys.exit(-1) - - if response == 'w': - logger.warning('Deleting %s', display_path(dest)) - rmtree(dest) - self.fetch_new(dest, url, rev_options) - return - - if response == 'b': - dest_dir = backup_dir(dest) - logger.warning( - 'Backing up %s to %s', display_path(dest), dest_dir, - ) - shutil.move(dest, dest_dir) - self.fetch_new(dest, url, rev_options) - return - - # Do nothing if the response is "i". - if response == 's': - logger.info( - 'Switching %s %s to %s%s', - self.repo_name, - display_path(dest), - url, - rev_display, - ) - self.switch(dest, url, rev_options) - - def unpack(self, location, url): - # type: (str, HiddenText) -> None - """ - Clean up current location and download the url repository - (and vcs infos) into location - - :param url: the repository URL starting with a vcs prefix. - """ - if os.path.exists(location): - rmtree(location) - self.obtain(location, url=url) - - @classmethod - def get_remote_url(cls, location): - # type: (str) -> str - """ - Return the url used at location - - Raises RemoteNotFoundError if the repository does not have a remote - url configured. - """ - raise NotImplementedError - - @classmethod - def get_revision(cls, location): - # type: (str) -> str - """ - Return the current commit id of the files at the given location. - """ - raise NotImplementedError - - @classmethod - def run_command( - cls, - cmd, # type: Union[List[str], CommandArgs] - show_stdout=True, # type: bool - cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] - extra_environ=None, # type: Optional[Mapping[str, Any]] - spinner=None, # type: Optional[SpinnerInterface] - log_failed_cmd=True # type: bool - ): - # type: (...) -> Text - """ - Run a VCS subcommand - This is simply a wrapper around call_subprocess that adds the VCS - command name, and checks that the VCS is available - """ - cmd = make_command(cls.name, *cmd) - try: - return call_subprocess(cmd, show_stdout, cwd, - on_returncode=on_returncode, - extra_ok_returncodes=extra_ok_returncodes, - command_desc=command_desc, - extra_environ=extra_environ, - unset_environ=cls.unset_environ, - spinner=spinner, - log_failed_cmd=log_failed_cmd) - except OSError as e: - # errno.ENOENT = no such file or directory - # In other words, the VCS executable isn't available - if e.errno == errno.ENOENT: - raise BadCommand( - 'Cannot find command {cls.name!r} - do you have ' - '{cls.name!r} installed and in your ' - 'PATH?'.format(**locals())) - else: - raise # re-raise exception if a different error occurred - - @classmethod - def is_repository_directory(cls, path): - # type: (str) -> bool - """ - Return whether a directory path is a repository directory. - """ - logger.debug('Checking in %s for %s (%s)...', - path, cls.dirname, cls.name) - return os.path.exists(os.path.join(path, cls.dirname)) - - @classmethod - def get_repository_root(cls, location): - # type: (str) -> Optional[str] - """ - Return the "root" (top-level) directory controlled by the vcs, - or `None` if the directory is not in any. - - It is meant to be overridden to implement smarter detection - mechanisms for specific vcs. - - This can do more than is_repository_directory() alone. For - example, the Git override checks that Git is actually available. - """ - if cls.is_repository_directory(location): - return location - return None diff --git a/env/lib/python3.8/site-packages/pip/_internal/wheel_builder.py b/env/lib/python3.8/site-packages/pip/_internal/wheel_builder.py deleted file mode 100644 index fcaeeb6c..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/wheel_builder.py +++ /dev/null @@ -1,309 +0,0 @@ -"""Orchestrator for building wheels from InstallRequirements. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import logging -import os.path -import re -import shutil - -from pip._internal.models.link import Link -from pip._internal.operations.build.wheel import build_wheel_pep517 -from pip._internal.operations.build.wheel_legacy import build_wheel_legacy -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ensure_dir, hash_file, is_wheel_installed -from pip._internal.utils.setuptools_build import make_setuptools_clean_args -from pip._internal.utils.subprocess import call_subprocess -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Any, Callable, Iterable, List, Optional, Pattern, Tuple, - ) - - from pip._internal.cache import WheelCache - from pip._internal.req.req_install import InstallRequirement - - BinaryAllowedPredicate = Callable[[InstallRequirement], bool] - BuildResult = Tuple[List[InstallRequirement], List[InstallRequirement]] - -logger = logging.getLogger(__name__) - - -def _contains_egg_info( - s, _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): - # type: (str, Pattern[str]) -> bool - """Determine whether the string looks like an egg_info. - - :param s: The string to parse. E.g. foo-2.1 - """ - return bool(_egg_info_re.search(s)) - - -def _should_build( - req, # type: InstallRequirement - need_wheel, # type: bool - check_binary_allowed, # type: BinaryAllowedPredicate -): - # type: (...) -> bool - """Return whether an InstallRequirement should be built into a wheel.""" - if req.constraint: - # never build requirements that are merely constraints - return False - if req.is_wheel: - if need_wheel: - logger.info( - 'Skipping %s, due to already being wheel.', req.name, - ) - return False - - if need_wheel: - # i.e. pip wheel, not pip install - return True - - # From this point, this concerns the pip install command only - # (need_wheel=False). - - if req.editable or not req.source_dir: - return False - - if not check_binary_allowed(req): - logger.info( - "Skipping wheel build for %s, due to binaries " - "being disabled for it.", req.name, - ) - return False - - if not req.use_pep517 and not is_wheel_installed(): - # we don't build legacy requirements if wheel is not installed - logger.info( - "Using legacy setup.py install for %s, " - "since package 'wheel' is not installed.", req.name, - ) - return False - - return True - - -def should_build_for_wheel_command( - req, # type: InstallRequirement -): - # type: (...) -> bool - return _should_build( - req, need_wheel=True, check_binary_allowed=_always_true - ) - - -def should_build_for_install_command( - req, # type: InstallRequirement - check_binary_allowed, # type: BinaryAllowedPredicate -): - # type: (...) -> bool - return _should_build( - req, need_wheel=False, check_binary_allowed=check_binary_allowed - ) - - -def _should_cache( - req, # type: InstallRequirement -): - # type: (...) -> Optional[bool] - """ - Return whether a built InstallRequirement can be stored in the persistent - wheel cache, assuming the wheel cache is available, and _should_build() - has determined a wheel needs to be built. - """ - if not should_build_for_install_command( - req, check_binary_allowed=_always_true - ): - # never cache if pip install would not have built - # (editable mode, etc) - return False - - if req.link and req.link.is_vcs: - # VCS checkout. Do not cache - # unless it points to an immutable commit hash. - assert not req.editable - assert req.source_dir - vcs_backend = vcs.get_backend_for_scheme(req.link.scheme) - assert vcs_backend - if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir): - return True - return False - - base, ext = req.link.splitext() - if _contains_egg_info(base): - return True - - # Otherwise, do not cache. - return False - - -def _get_cache_dir( - req, # type: InstallRequirement - wheel_cache, # type: WheelCache -): - # type: (...) -> str - """Return the persistent or temporary cache directory where the built - wheel need to be stored. - """ - cache_available = bool(wheel_cache.cache_dir) - if cache_available and _should_cache(req): - cache_dir = wheel_cache.get_path_for_link(req.link) - else: - cache_dir = wheel_cache.get_ephem_path_for_link(req.link) - return cache_dir - - -def _always_true(_): - # type: (Any) -> bool - return True - - -def _build_one( - req, # type: InstallRequirement - output_dir, # type: str - build_options, # type: List[str] - global_options, # type: List[str] -): - # type: (...) -> Optional[str] - """Build one wheel. - - :return: The filename of the built wheel, or None if the build failed. - """ - try: - ensure_dir(output_dir) - except OSError as e: - logger.warning( - "Building wheel for %s failed: %s", - req.name, e, - ) - return None - - # Install build deps into temporary directory (PEP 518) - with req.build_env: - return _build_one_inside_env( - req, output_dir, build_options, global_options - ) - - -def _build_one_inside_env( - req, # type: InstallRequirement - output_dir, # type: str - build_options, # type: List[str] - global_options, # type: List[str] -): - # type: (...) -> Optional[str] - with TempDirectory(kind="wheel") as temp_dir: - if req.use_pep517: - wheel_path = build_wheel_pep517( - name=req.name, - backend=req.pep517_backend, - metadata_directory=req.metadata_directory, - build_options=build_options, - tempd=temp_dir.path, - ) - else: - wheel_path = build_wheel_legacy( - name=req.name, - setup_py_path=req.setup_py_path, - source_dir=req.unpacked_source_directory, - global_options=global_options, - build_options=build_options, - tempd=temp_dir.path, - ) - - if wheel_path is not None: - wheel_name = os.path.basename(wheel_path) - dest_path = os.path.join(output_dir, wheel_name) - try: - wheel_hash, length = hash_file(wheel_path) - shutil.move(wheel_path, dest_path) - logger.info('Created wheel for %s: ' - 'filename=%s size=%d sha256=%s', - req.name, wheel_name, length, - wheel_hash.hexdigest()) - logger.info('Stored in directory: %s', output_dir) - return dest_path - except Exception as e: - logger.warning( - "Building wheel for %s failed: %s", - req.name, e, - ) - # Ignore return, we can't do anything else useful. - if not req.use_pep517: - _clean_one_legacy(req, global_options) - return None - - -def _clean_one_legacy(req, global_options): - # type: (InstallRequirement, List[str]) -> bool - clean_args = make_setuptools_clean_args( - req.setup_py_path, - global_options=global_options, - ) - - logger.info('Running setup.py clean for %s', req.name) - try: - call_subprocess(clean_args, cwd=req.source_dir) - return True - except Exception: - logger.error('Failed cleaning build dir for %s', req.name) - return False - - -def build( - requirements, # type: Iterable[InstallRequirement] - wheel_cache, # type: WheelCache - build_options, # type: List[str] - global_options, # type: List[str] -): - # type: (...) -> BuildResult - """Build wheels. - - :return: The list of InstallRequirement that succeeded to build and - the list of InstallRequirement that failed to build. - """ - if not requirements: - return [], [] - - # Build the wheels. - logger.info( - 'Building wheels for collected packages: %s', - ', '.join(req.name for req in requirements), - ) - - with indent_log(): - build_successes, build_failures = [], [] - for req in requirements: - cache_dir = _get_cache_dir(req, wheel_cache) - wheel_file = _build_one( - req, cache_dir, build_options, global_options - ) - if wheel_file: - # Update the link for this. - req.link = Link(path_to_url(wheel_file)) - req.local_file_path = req.link.file_path - assert req.link.is_wheel - build_successes.append(req) - else: - build_failures.append(req) - - # notify success/failure - if build_successes: - logger.info( - 'Successfully built %s', - ' '.join([req.name for req in build_successes]), - ) - if build_failures: - logger.info( - 'Failed to build %s', - ' '.join([req.name for req in build_failures]), - ) - # Return a list of requirements that failed to build - return build_successes, build_failures diff --git a/env/lib/python3.8/site-packages/pip/_vendor/__init__.py b/env/lib/python3.8/site-packages/pip/_vendor/__init__.py deleted file mode 100644 index d4e20fed..00000000 --- a/env/lib/python3.8/site-packages/pip/_vendor/__init__.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -pip._vendor is for vendoring dependencies of pip to prevent needing pip to -depend on something external. - -Files inside of pip._vendor should be considered immutable and should only be -updated to versions from upstream. -""" -from __future__ import absolute_import - -import glob -import os.path -import sys - -# Downstream redistributors which have debundled our dependencies should also -# patch this value to be true. This will trigger the additional patching -# to cause things like "six" to be available as pip. -DEBUNDLED = True - -# By default, look in this directory for a bunch of .whl files which we will -# add to the beginning of sys.path before attempting to import anything. This -# is done to support downstream re-distributors like Debian and Fedora who -# wish to create their own Wheels for our dependencies to aid in debundling. -prefix = getattr(sys, "base_prefix", sys.prefix) -if prefix.startswith('/usr/lib/pypy'): - prefix = '/usr' -WHEEL_DIR = os.path.abspath(os.path.join(prefix, 'share', 'python-wheels')) - - -# Define a small helper function to alias our vendored modules to the real ones -# if the vendored ones do not exist. This idea of this was taken from -# https://github.com/kennethreitz/requests/pull/2567. -def vendored(modulename): - vendored_name = "{0}.{1}".format(__name__, modulename) - - try: - __import__(modulename, globals(), locals(), level=0) - except ImportError: - # We can just silently allow import failures to pass here. If we - # got to this point it means that ``import pip._vendor.whatever`` - # failed and so did ``import whatever``. Since we're importing this - # upfront in an attempt to alias imports, not erroring here will - # just mean we get a regular import error whenever pip *actually* - # tries to import one of these modules to use it, which actually - # gives us a better error message than we would have otherwise - # gotten. - pass - else: - sys.modules[vendored_name] = sys.modules[modulename] - base, head = vendored_name.rsplit(".", 1) - setattr(sys.modules[base], head, sys.modules[modulename]) - - -# If we're operating in a debundled setup, then we want to go ahead and trigger -# the aliasing of our vendored libraries as well as looking for wheels to add -# to our sys.path. This will cause all of this code to be a no-op typically -# however downstream redistributors can enable it in a consistent way across -# all platforms. -if DEBUNDLED: - # Actually look inside of WHEEL_DIR to find .whl files and add them to the - # front of our sys.path. - sys.path[:] = [fn for fn in glob.iglob(os.path.join(WHEEL_DIR, '*.whl')) - if not (os.path.basename(fn).startswith('wheel') or - os.path.basename(fn).startswith('pip'))] + sys.path - - # Actually alias all of our vendored dependencies. - vendored("appdirs") - vendored("cachecontrol") - vendored("certifi") - vendored("colorama") - vendored("contextlib2") - vendored("distlib") - vendored("distro") - vendored("html5lib") - vendored("six") - vendored("six.moves") - vendored("six.moves.urllib") - vendored("six.moves.urllib.parse") - vendored("packaging") - vendored("packaging.version") - vendored("packaging.specifiers") - vendored("pep517") - vendored("pkg_resources") - vendored("progress") - vendored("retrying") - vendored("requests") - vendored("requests.exceptions") - vendored("requests.packages") - vendored("requests.packages.urllib3") - vendored("requests.packages.urllib3._collections") - vendored("requests.packages.urllib3.connection") - vendored("requests.packages.urllib3.connectionpool") - vendored("requests.packages.urllib3.contrib") - vendored("requests.packages.urllib3.contrib.ntlmpool") - vendored("requests.packages.urllib3.contrib.pyopenssl") - vendored("requests.packages.urllib3.exceptions") - vendored("requests.packages.urllib3.fields") - vendored("requests.packages.urllib3.filepost") - vendored("requests.packages.urllib3.packages") - try: - vendored("requests.packages.urllib3.packages.ordered_dict") - vendored("requests.packages.urllib3.packages.six") - except ImportError: - # Debian already unbundles these from requests. - pass - vendored("requests.packages.urllib3.packages.ssl_match_hostname") - vendored("requests.packages.urllib3.packages.ssl_match_hostname." - "_implementation") - vendored("requests.packages.urllib3.poolmanager") - vendored("requests.packages.urllib3.request") - vendored("requests.packages.urllib3.response") - vendored("requests.packages.urllib3.util") - vendored("requests.packages.urllib3.util.connection") - vendored("requests.packages.urllib3.util.request") - vendored("requests.packages.urllib3.util.response") - vendored("requests.packages.urllib3.util.retry") - vendored("requests.packages.urllib3.util.ssl_") - vendored("requests.packages.urllib3.util.timeout") - vendored("requests.packages.urllib3.util.url") - vendored("resolvelib") - vendored("toml") - vendored("toml.encoder") - vendored("toml.decoder") - vendored("urllib3") diff --git a/env/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 9800c690147554e4dfaaacf0a0bb08b2801ba46e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3281 zcmbW3-E!MR6vuZZS+KpIZTca%4S@ood?gIbFumYoC>|IgYd5hHNh@~O zX)Thg09P;rZxCPd8ax0Gu)`f!yaE>tXXTA4FmajMAT1B_x5~owA4eF8_b$6PF zcBe_3M;>v9n7>Qv(5mfB9Zgqdi#ADvG>7&OcV>u3roKjfkZ46hpohHcGq0e0Yq>A9)- z3Cb58L{IH{KVbd~M*90H%B_2PuWlLTs^JTUYlbfxzGQgY@MXhS3|}=|H+;?Tj^XQu zZy3I5_?F?@n#BGPt!$LPdPPzM;U3Ki<9;IiEx@Ri1&q)_C{)-<-TAUl|4N~A4tmcC=ERCog@V-NiGsXjj{2YMUVAU;&-VZvr51z z@slj;%cz@DKgx-3BrHz{p!50#i6n?%I(w9h1RnFZILrKgAta|!7I?qw)3t)tY}6Gj z?MoUaS;4rx`;nUJMuLX0j;-WD*=qL%Z>LGOT?~pr>FB1aiC)BM*(wII$MWm4D%?XVW_;&>;}~9+bQctsZegpV$G@ds*T#@oN;A~ zfl&2~kv{lOxm*-!B2`^b8A-`k9OaG1v|-g61rH_Fdz7R1Svfr#k)IG>gxURZyDhV# z4Iy*ApBGWQOUY<+ufN>y4pzH^RFAbyNVZ{?c_PCwC@24qkZ)GwF4~C4nDH>@em)`1P!rp{?P;d!r8|^T3GU8I)Ph=1DR&YaETY0tQQE>)duDta$5i(|3 zapyH?3mrc$vhX~f|C67GMp?TO-0!8T9u);ixKPt^6!$2c3dtFC$CS%tD^ZP@rHn^e zq^9&395aaDTdGdLJk*q{E1aoDPiEsVf)$?h*x!VRCRBm0Qqa?dD6WRqSquoC?tH|g zk*vJ@e^doyX?cF4QgYbdE02@}xlG~Ufw`-X))oT>m$MLQIbkgi?W2FPNpM+8MEUF_ zMM?`M9$|7kw+R7f48qYapL>Kk?WswwuT04#qpUwM?kXKzVan6@ObUq)ZaYV^EG?&X z8NmM+2GM3(1TIr(sru;FTV0t~^)MtX9wo)CzU*^IkX&aD<><_)>P)~@D0}=V=;Jeb zpt-U6*2i}@-rwAS>^aJWaOYM3C-^z7I;&N6_~%ij31^2TxoUp$?&jwE;l_I(REbK} z5^bKhv|i`Nhl(m&G}cF%^^VTs;yWmu`n1)+@U1!S4EC^tm)ypau6@>W{+y{*BYO0) TzZN_>jpr;^TNu6RL|cCWzj5qk diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt deleted file mode 100644 index 04c42fc2..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt +++ /dev/null @@ -1,566 +0,0 @@ -@Switch01 -A_Rog -Aakanksha Agrawal -Abhinav Sagar -ABHYUDAY PRATAP SINGH -abs51295 -AceGentile -Adam Chainz -Adam Tse -Adam Wentz -admin -Adrien Morison -ahayrapetyan -Ahilya -AinsworthK -Akash Srivastava -Alan Yee -Albert Tugushev -Albert-Guan -albertg -Aleks Bunin -Alethea Flowers -Alex Gaynor -Alex Grönholm -Alex Loosley -Alex Morega -Alex Stachowiak -Alexander Shtyrov -Alexandre Conrad -Alexey Popravka -Alli -Ami Fischman -Ananya Maiti -Anatoly Techtonik -Anders Kaseorg -Andre Aguiar -Andreas Lutro -Andrei Geacar -Andrew Gaul -Andrey Bulgakov -Andrés Delfino -Andy Freeland -Andy Kluger -Ani Hayrapetyan -Aniruddha Basak -Anish Tambe -Anrs Hu -Anthony Sottile -Antoine Musso -Anton Ovchinnikov -Anton Patrushev -Antonio Alvarado Hernandez -Antony Lee -Antti Kaihola -Anubhav Patel -Anudit Nagar -Anuj Godase -AQNOUCH Mohammed -AraHaan -Arindam Choudhury -Armin Ronacher -Artem -Ashley Manton -Ashwin Ramaswami -atse -Atsushi Odagiri -Avner Cohen -Baptiste Mispelon -Barney Gale -barneygale -Bartek Ogryczak -Bastian Venthur -Ben Darnell -Ben Hoyt -Ben Rosser -Bence Nagy -Benjamin Peterson -Benjamin VanEvery -Benoit Pierre -Berker Peksag -Bernardo B. Marques -Bernhard M. Wiedemann -Bertil Hatt -Bhavam Vidyarthi -Bogdan Opanchuk -BorisZZZ -Brad Erickson -Bradley Ayers -Brandon L. Reiss -Brandt Bucher -Brett Randall -Brian Cristante -Brian Rosner -BrownTruck -Bruno Oliveira -Bruno Renié -Bstrdsmkr -Buck Golemon -burrows -Bussonnier Matthias -c22 -Caleb Martinez -Calvin Smith -Carl Meyer -Carlos Liam -Carol Willing -Carter Thayer -Cass -Chandrasekhar Atina -Chih-Hsuan Yen -Chris Brinker -Chris Hunt -Chris Jerdonek -Chris McDonough -Chris Wolfe -Christian Clauss -Christian Heimes -Christian Oudard -Christoph Reiter -Christopher Hunt -Christopher Snyder -cjc7373 -Clark Boylan -Clay McClure -Cody -Cody Soyland -Colin Watson -Connor Osborn -Cooper Lees -Cooper Ry Lees -Cory Benfield -Cory Wright -Craig Kerstiens -Cristian Sorinel -Curtis Doty -cytolentino -Damian Quiroga -Dan Black -Dan Savilonis -Dan Sully -daniel -Daniel Collins -Daniel Hahler -Daniel Holth -Daniel Jost -Daniel Shaulov -Daniele Esposti -Daniele Procida -Danny Hermes -Danny McClanahan -Dav Clark -Dave Abrahams -Dave Jones -David Aguilar -David Black -David Bordeynik -David Caro -David Evans -David Linke -David Pursehouse -David Tucker -David Wales -Davidovich -Deepak Sharma -derwolfe -Desetude -Devesh Kumar Singh -Diego Caraballo -DiegoCaraballo -Dmitry Gladkov -Domen Kožar -Donald Stufft -Dongweiming -Douglas Thor -DrFeathers -Dustin Ingram -Dwayne Bailey -Ed Morley -Eitan Adler -ekristina -elainechan -Eli Schwartz -Ellen Marie Dash -Emil Burzo -Emil Styrke -Endoh Takanao -enoch -Erdinc Mutlu -Eric Gillingham -Eric Hanchrow -Eric Hopper -Erik M. Bray -Erik Rose -Ernest W Durbin III -Ernest W. Durbin III -Erwin Janssen -Eugene Vereshchagin -everdimension -Felix Yan -fiber-space -Filip Kokosiński -Florian Briand -Florian Rathgeber -Francesco -Francesco Montesano -Frost Ming -Gabriel Curio -Gabriel de Perthuis -Garry Polley -gdanielson -Geoffrey Lehée -Geoffrey Sneddon -George Song -Georgi Valkov -ghost -Giftlin Rajaiah -gizmoguy1 -gkdoc -Gopinath M -GOTO Hayato -gpiks -Guilherme Espada -gutsytechster -Guy Rozendorn -gzpan123 -Hanjun Kim -Hari Charan -Harsh Vardhan -Herbert Pfennig -Hsiaoming Yang -Hugo -Hugo Lopes Tavares -Hugo van Kemenade -hugovk -Hynek Schlawack -Ian Bicking -Ian Cordasco -Ian Lee -Ian Stapleton Cordasco -Ian Wienand -Igor Kuzmitshov -Igor Sobreira -Ilan Schnell -Ilya Baryshev -INADA Naoki -Ionel Cristian Mărieș -Ionel Maries Cristian -Ivan Pozdeev -Jacob Kim -jakirkham -Jakub Stasiak -Jakub Vysoky -Jakub Wilk -James Cleveland -James Firth -James Polley -Jan Pokorný -Jannis Leidel -jarondl -Jason R. Coombs -Jay Graves -Jean-Christophe Fillion-Robin -Jeff Barber -Jeff Dairiki -Jelmer Vernooij -jenix21 -Jeremy Stanley -Jeremy Zafran -Jiashuo Li -Jim Garrison -Jivan Amara -John Paton -John T. Wodder II -John-Scott Atlakson -johnthagen -Jon Banafato -Jon Dufresne -Jon Parise -Jonas Nockert -Jonathan Herbert -Joost Molenaar -Jorge Niedbalski -Joseph Long -Josh Bronson -Josh Hansen -Josh Schneier -Juanjo Bazán -Julian Berman -Julian Gethmann -Julien Demoor -jwg4 -Jyrki Pulliainen -Kai Chen -Kamal Bin Mustafa -kaustav haldar -keanemind -Keith Maxwell -Kelsey Hightower -Kenneth Belitzky -Kenneth Reitz -Kevin Burke -Kevin Carter -Kevin Frommelt -Kevin R Patterson -Kexuan Sun -Kit Randel -KOLANICH -kpinc -Krishna Oza -Kumar McMillan -Kyle Persohn -lakshmanaram -Laszlo Kiss-Kollar -Laurent Bristiel -Laurie Opperman -Leon Sasson -Lev Givon -Lincoln de Sousa -Lipis -Loren Carvalho -Lucas Cimon -Ludovic Gasc -Luke Macken -Luo Jiebin -luojiebin -luz.paz -László Kiss Kollár -Marc Abramowitz -Marc Tamlyn -Marcus Smith -Mariatta -Mark Kohler -Mark Williams -Markus Hametner -Masaki -Masklinn -Matej Stuchlik -Mathew Jennings -Mathieu Bridon -Matt Good -Matt Maker -Matt Robenolt -matthew -Matthew Einhorn -Matthew Gilliard -Matthew Iversen -Matthew Trumbell -Matthew Willson -Matthias Bussonnier -mattip -Maxim Kurnikov -Maxime Rouyrre -mayeut -mbaluna -mdebi -memoselyk -Michael -Michael Aquilina -Michael E. Karpeles -Michael Klich -Michael Williamson -michaelpacer -Mickaël Schoentgen -Miguel Araujo Perez -Mihir Singh -Mike -Mike Hendricks -Min RK -MinRK -Miro Hrončok -Monica Baluna -montefra -Monty Taylor -Nate Coraor -Nathaniel J. Smith -Nehal J Wani -Neil Botelho -Nguyễn Gia Phong -Nick Coghlan -Nick Stenning -Nick Timkovich -Nicolas Bock -Nikhil Benesch -Nikolay Korolev -Nitesh Sharma -Noah Gorny -Nowell Strite -NtaleGrey -nvdv -Ofekmeister -ofrinevo -Oliver Jeeves -Oliver Tonnhofer -Olivier Girardot -Olivier Grisel -Ollie Rutherfurd -OMOTO Kenji -Omry Yadan -onlinejudge95 -Oren Held -Oscar Benjamin -Oz N Tiram -Pachwenko -Patrick Dubroy -Patrick Jenkins -Patrick Lawson -patricktokeeffe -Patrik Kopkan -Paul Kehrer -Paul Moore -Paul Nasrat -Paul Oswald -Paul van der Linden -Paulus Schoutsen -Pavithra Eswaramoorthy -Pawel Jasinski -Pekka Klärck -Peter Lisák -Peter Waller -petr-tik -Phaneendra Chiruvella -Phil Freo -Phil Pennock -Phil Whelan -Philip Jägenstedt -Philip Molloy -Philippe Ombredanne -Pi Delport -Pierre-Yves Rofes -pip -Prabakaran Kumaresshan -Prabhjyotsing Surjit Singh Sodhi -Prabhu Marappan -Pradyun Gedam -Prashant Sharma -Pratik Mallya -Preet Thakkar -Preston Holmes -Przemek Wrzos -Pulkit Goyal -Qiangning Hong -Quentin Pradet -R. David Murray -Rafael Caricio -Ralf Schmitt -Razzi Abuissa -rdb -Reece Dunham -Remi Rampin -Rene Dudfield -Riccardo Magliocchetti -Richard Jones -Ricky Ng-Adam -RobberPhex -Robert Collins -Robert McGibbon -Robert T. McGibbon -robin elisha robinson -Roey Berman -Rohan Jain -Roman Bogorodskiy -Romuald Brunet -Ronny Pfannschmidt -Rory McCann -Ross Brattain -Roy Wellington Ⅳ -Ryan Wooden -ryneeverett -Sachi King -Salvatore Rinchiera -Savio Jomton -schlamar -Scott Kitterman -Sean -seanj -Sebastian Jordan -Sebastian Schaetz -Segev Finer -SeongSoo Cho -Sergey Vasilyev -Seth Woodworth -Shlomi Fish -Shovan Maity -Simeon Visser -Simon Cross -Simon Pichugin -sinoroc -sinscary -Sorin Sbarnea -Stavros Korokithakis -Stefan Scherfke -Stefano Rivera -Stephan Erb -stepshal -Steve (Gadget) Barnes -Steve Barnes -Steve Dower -Steve Kowalik -Steven Myint -stonebig -Stéphane Bidoul -Stéphane Bidoul (ACSONE) -Stéphane Klein -Sumana Harihareswara -Sviatoslav Sydorenko -Swat009 -Takayuki SHIMIZUKAWA -tbeswick -Thijs Triemstra -Thomas Fenzl -Thomas Grainger -Thomas Guettler -Thomas Johansson -Thomas Kluyver -Thomas Smith -Tim D. Smith -Tim Gates -Tim Harder -Tim Heap -tim smith -tinruufu -Tom Forbes -Tom Freudenheim -Tom V -Tomas Hrnciar -Tomas Orsava -Tomer Chachamu -Tony Beswick -Tony Zhaocheng Tan -TonyBeswick -toonarmycaptain -Toshio Kuratomi -Travis Swicegood -Tzu-ping Chung -Valentin Haenel -Victor Stinner -victorvpaulo -Viktor Szépe -Ville Skyttä -Vinay Sajip -Vincent Philippon -Vinicyus Macedo -Vitaly Babiy -Vladimir Rutsky -W. Trevor King -Wil Tan -Wilfred Hughes -William ML Leslie -William T Olson -Wilson Mo -wim glenn -Wolfgang Maier -Xavier Fernandez -xoviat -xtreak -YAMAMOTO Takashi -Yen Chi Hsuan -Yeray Diaz Diaz -Yoval P -Yu Jian -Yuan Jing Vincent Yan -Zearin -Zhiping Deng -Zvezdan Petkovic -Łukasz Langa -Семён Марьясин diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt deleted file mode 100644 index 737fec5c..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2019 The pip developers (see AUTHORS.txt file) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/METADATA b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/METADATA deleted file mode 100644 index cf6c9302..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/METADATA +++ /dev/null @@ -1,13 +0,0 @@ -Metadata-Version: 2.1 -Name: pkg_resources -Version: 0.0.0 -Summary: UNKNOWN -Home-page: UNKNOWN -Author: UNKNOWN -Author-email: UNKNOWN -License: UNKNOWN -Platform: UNKNOWN - -UNKNOWN - - diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/RECORD b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/RECORD deleted file mode 100644 index 562db114..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/RECORD +++ /dev/null @@ -1,38 +0,0 @@ -pkg_resources-0.0.0.dist-info/AUTHORS.txt,sha256=RnTFYKrTgbpfWnZMizLRq0u31iGDJMbs-iqvafo1CcA,7734 -pkg_resources-0.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pkg_resources-0.0.0.dist-info/LICENSE.txt,sha256=W6Ifuwlk-TatfRU2LR7W1JMcyMj5_y1NkRkOEJvnRDE,1090 -pkg_resources-0.0.0.dist-info/METADATA,sha256=V9_WPOtD1FnuKrTGv6Ique7kAOn2lasvT8W0_iMCCCk,177 -pkg_resources-0.0.0.dist-info/RECORD,, -pkg_resources-0.0.0.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -pkg_resources/__init__.py,sha256=0IssxXPnaDKpYZRra8Ime0JG4hwosQljItGD0bnIkGk,108349 -pkg_resources/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/__pycache__/py31compat.cpython-38.pyc,, -pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/six.cpython-38.pyc,, -pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701 -pkg_resources/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 -pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 -pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc,, -pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 -pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 -pkg_resources/_vendor/packaging/markers.py,sha256=uEcBBtGvzqltgnArqb9c4RrcInXezDLos14zbBHhWJo,8248 -pkg_resources/_vendor/packaging/requirements.py,sha256=SikL2UynbsT0qtY9ltqngndha_sfo0w6XGFhAhoSoaQ,4355 -pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 -pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 -pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 -pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 -pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 -pkg_resources/extern/__init__.py,sha256=cHiEfHuLmm6rs5Ve_ztBfMI7Lr31vss-D4wkqF5xzlI,2498 -pkg_resources/extern/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558 diff --git a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/WHEEL b/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/WHEEL deleted file mode 100644 index ef99c6cf..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/pkg_resources/__init__.py b/env/lib/python3.8/site-packages/pkg_resources/__init__.py deleted file mode 100644 index 2f5aa64a..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/__init__.py +++ /dev/null @@ -1,3296 +0,0 @@ -# coding: utf-8 -""" -Package resource API --------------------- - -A resource is a logical file contained within a package, or a logical -subdirectory thereof. The package resource API expects resource names -to have their path parts separated with ``/``, *not* whatever the local -path separator is. Do not use os.path operations to manipulate resource -names being passed into the API. - -The package resource API is designed to work with normal filesystem packages, -.egg files, and unpacked .egg files. It can also work in a limited way with -.zip files and with custom PEP 302 loaders that support the ``get_data()`` -method. -""" - -from __future__ import absolute_import - -import sys -import os -import io -import time -import re -import types -import zipfile -import zipimport -import warnings -import stat -import functools -import pkgutil -import operator -import platform -import collections -import plistlib -import email.parser -import errno -import tempfile -import textwrap -import itertools -import inspect -import ntpath -import posixpath -from pkgutil import get_importer - -try: - import _imp -except ImportError: - # Python 3.2 compatibility - import imp as _imp - -try: - FileExistsError -except NameError: - FileExistsError = OSError - -from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib, map, filter - -# capture these to bypass sandboxing -from os import utime -try: - from os import mkdir, rename, unlink - WRITE_SUPPORT = True -except ImportError: - # no write support, probably under GAE - WRITE_SUPPORT = False - -from os import open as os_open -from os.path import isdir, split - -try: - import importlib.machinery as importlib_machinery - # access attribute to force import under delayed import mechanisms. - importlib_machinery.__name__ -except ImportError: - importlib_machinery = None - -from . import py31compat -from pkg_resources.extern import appdirs -from pkg_resources.extern import packaging -__import__('pkg_resources.extern.packaging.version') -__import__('pkg_resources.extern.packaging.specifiers') -__import__('pkg_resources.extern.packaging.requirements') -__import__('pkg_resources.extern.packaging.markers') - - -__metaclass__ = type - - -if (3, 0) < sys.version_info < (3, 5): - raise RuntimeError("Python 3.5 or later is required") - -if six.PY2: - # Those builtin exceptions are only defined in Python 3 - PermissionError = None - NotADirectoryError = None - -# declare some globals that will be defined later to -# satisfy the linters. -require = None -working_set = None -add_activation_listener = None -resources_stream = None -cleanup_resources = None -resource_dir = None -resource_stream = None -set_extraction_path = None -resource_isdir = None -resource_string = None -iter_entry_points = None -resource_listdir = None -resource_filename = None -resource_exists = None -_distribution_finders = None -_namespace_handlers = None -_namespace_packages = None - - -class PEP440Warning(RuntimeWarning): - """ - Used when there is an issue with a version or specifier not complying with - PEP 440. - """ - - -def parse_version(v): - try: - return packaging.version.Version(v) - except packaging.version.InvalidVersion: - return packaging.version.LegacyVersion(v) - - -_state_vars = {} - - -def _declare_state(vartype, **kw): - globals().update(kw) - _state_vars.update(dict.fromkeys(kw, vartype)) - - -def __getstate__(): - state = {} - g = globals() - for k, v in _state_vars.items(): - state[k] = g['_sget_' + v](g[k]) - return state - - -def __setstate__(state): - g = globals() - for k, v in state.items(): - g['_sset_' + _state_vars[k]](k, g[k], v) - return state - - -def _sget_dict(val): - return val.copy() - - -def _sset_dict(key, ob, state): - ob.clear() - ob.update(state) - - -def _sget_object(val): - return val.__getstate__() - - -def _sset_object(key, ob, state): - ob.__setstate__(state) - - -_sget_none = _sset_none = lambda *args: None - - -def get_supported_platform(): - """Return this platform's maximum compatible version. - - distutils.util.get_platform() normally reports the minimum version - of Mac OS X that would be required to *use* extensions produced by - distutils. But what we want when checking compatibility is to know the - version of Mac OS X that we are *running*. To allow usage of packages that - explicitly require a newer version of Mac OS X, we must also know the - current version of the OS. - - If this condition occurs for any other platform with a version in its - platform strings, this function should be extended accordingly. - """ - plat = get_build_platform() - m = macosVersionString.match(plat) - if m is not None and sys.platform == "darwin": - try: - plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) - except ValueError: - # not Mac OS X - pass - return plat - - -__all__ = [ - # Basic resource access and distribution/entry point discovery - 'require', 'run_script', 'get_provider', 'get_distribution', - 'load_entry_point', 'get_entry_map', 'get_entry_info', - 'iter_entry_points', - 'resource_string', 'resource_stream', 'resource_filename', - 'resource_listdir', 'resource_exists', 'resource_isdir', - - # Environmental control - 'declare_namespace', 'working_set', 'add_activation_listener', - 'find_distributions', 'set_extraction_path', 'cleanup_resources', - 'get_default_cache', - - # Primary implementation classes - 'Environment', 'WorkingSet', 'ResourceManager', - 'Distribution', 'Requirement', 'EntryPoint', - - # Exceptions - 'ResolutionError', 'VersionConflict', 'DistributionNotFound', - 'UnknownExtra', 'ExtractionError', - - # Warnings - 'PEP440Warning', - - # Parsing functions and string utilities - 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', - 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', - 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', - - # filesystem utilities - 'ensure_directory', 'normalize_path', - - # Distribution "precedence" constants - 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', - - # "Provider" interfaces, implementations, and registration/lookup APIs - 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', - 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', - 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', - 'register_finder', 'register_namespace_handler', 'register_loader_type', - 'fixup_namespace_packages', 'get_importer', - - # Warnings - 'PkgResourcesDeprecationWarning', - - # Deprecated/backward compatibility only - 'run_main', 'AvailableDistributions', -] - - -class ResolutionError(Exception): - """Abstract base for dependency resolution errors""" - - def __repr__(self): - return self.__class__.__name__ + repr(self.args) - - -class VersionConflict(ResolutionError): - """ - An already-installed version conflicts with the requested version. - - Should be initialized with the installed Distribution and the requested - Requirement. - """ - - _template = "{self.dist} is installed but {self.req} is required" - - @property - def dist(self): - return self.args[0] - - @property - def req(self): - return self.args[1] - - def report(self): - return self._template.format(**locals()) - - def with_context(self, required_by): - """ - If required_by is non-empty, return a version of self that is a - ContextualVersionConflict. - """ - if not required_by: - return self - args = self.args + (required_by,) - return ContextualVersionConflict(*args) - - -class ContextualVersionConflict(VersionConflict): - """ - A VersionConflict that accepts a third parameter, the set of the - requirements that required the installed Distribution. - """ - - _template = VersionConflict._template + ' by {self.required_by}' - - @property - def required_by(self): - return self.args[2] - - -class DistributionNotFound(ResolutionError): - """A requested distribution was not found""" - - _template = ("The '{self.req}' distribution was not found " - "and is required by {self.requirers_str}") - - @property - def req(self): - return self.args[0] - - @property - def requirers(self): - return self.args[1] - - @property - def requirers_str(self): - if not self.requirers: - return 'the application' - return ', '.join(self.requirers) - - def report(self): - return self._template.format(**locals()) - - def __str__(self): - return self.report() - - -class UnknownExtra(ResolutionError): - """Distribution doesn't have an "extra feature" of the given name""" - - -_provider_factories = {} - -PY_MAJOR = '{}.{}'.format(*sys.version_info) -EGG_DIST = 3 -BINARY_DIST = 2 -SOURCE_DIST = 1 -CHECKOUT_DIST = 0 -DEVELOP_DIST = -1 - - -def register_loader_type(loader_type, provider_factory): - """Register `provider_factory` to make providers for `loader_type` - - `loader_type` is the type or class of a PEP 302 ``module.__loader__``, - and `provider_factory` is a function that, passed a *module* object, - returns an ``IResourceProvider`` for that module. - """ - _provider_factories[loader_type] = provider_factory - - -def get_provider(moduleOrReq): - """Return an IResourceProvider for the named module or requirement""" - if isinstance(moduleOrReq, Requirement): - return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] - try: - module = sys.modules[moduleOrReq] - except KeyError: - __import__(moduleOrReq) - module = sys.modules[moduleOrReq] - loader = getattr(module, '__loader__', None) - return _find_adapter(_provider_factories, loader)(module) - - -def _macosx_vers(_cache=[]): - if not _cache: - version = platform.mac_ver()[0] - # fallback for MacPorts - if version == '': - plist = '/System/Library/CoreServices/SystemVersion.plist' - if os.path.exists(plist): - if hasattr(plistlib, 'readPlist'): - plist_content = plistlib.readPlist(plist) - if 'ProductVersion' in plist_content: - version = plist_content['ProductVersion'] - - _cache.append(version.split('.')) - return _cache[0] - - -def _macosx_arch(machine): - return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) - - -def get_build_platform(): - """Return this platform's string for platform-specific distributions - - XXX Currently this is the same as ``distutils.util.get_platform()``, but it - needs some hacks for Linux and Mac OS X. - """ - from sysconfig import get_platform - - plat = get_platform() - if sys.platform == "darwin" and not plat.startswith('macosx-'): - try: - version = _macosx_vers() - machine = os.uname()[4].replace(" ", "_") - return "macosx-%d.%d-%s" % ( - int(version[0]), int(version[1]), - _macosx_arch(machine), - ) - except ValueError: - # if someone is running a non-Mac darwin system, this will fall - # through to the default implementation - pass - return plat - - -macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") -darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") -# XXX backward compat -get_platform = get_build_platform - - -def compatible_platforms(provided, required): - """Can code for the `provided` platform run on the `required` platform? - - Returns true if either platform is ``None``, or the platforms are equal. - - XXX Needs compatibility checks for Linux and other unixy OSes. - """ - if provided is None or required is None or provided == required: - # easy case - return True - - # Mac OS X special cases - reqMac = macosVersionString.match(required) - if reqMac: - provMac = macosVersionString.match(provided) - - # is this a Mac package? - if not provMac: - # this is backwards compatibility for packages built before - # setuptools 0.6. All packages built after this point will - # use the new macosx designation. - provDarwin = darwinVersionString.match(provided) - if provDarwin: - dversion = int(provDarwin.group(1)) - macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) - if dversion == 7 and macosversion >= "10.3" or \ - dversion == 8 and macosversion >= "10.4": - return True - # egg isn't macosx or legacy darwin - return False - - # are they the same major version and machine type? - if provMac.group(1) != reqMac.group(1) or \ - provMac.group(3) != reqMac.group(3): - return False - - # is the required OS major update >= the provided one? - if int(provMac.group(2)) > int(reqMac.group(2)): - return False - - return True - - # XXX Linux and other platforms' special cases should go here - return False - - -def run_script(dist_spec, script_name): - """Locate distribution `dist_spec` and run its `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - require(dist_spec)[0].run_script(script_name, ns) - - -# backward compatibility -run_main = run_script - - -def get_distribution(dist): - """Return a current distribution object for a Requirement or string""" - if isinstance(dist, six.string_types): - dist = Requirement.parse(dist) - if isinstance(dist, Requirement): - dist = get_provider(dist) - if not isinstance(dist, Distribution): - raise TypeError("Expected string, Requirement, or Distribution", dist) - return dist - - -def load_entry_point(dist, group, name): - """Return `name` entry point of `group` for `dist` or raise ImportError""" - return get_distribution(dist).load_entry_point(group, name) - - -def get_entry_map(dist, group=None): - """Return the entry point map for `group`, or the full entry map""" - return get_distribution(dist).get_entry_map(group) - - -def get_entry_info(dist, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return get_distribution(dist).get_entry_info(group, name) - - -class IMetadataProvider: - def has_metadata(name): - """Does the package's distribution contain the named metadata?""" - - def get_metadata(name): - """The named metadata resource as a string""" - - def get_metadata_lines(name): - """Yield named metadata resource as list of non-blank non-comment lines - - Leading and trailing whitespace is stripped from each line, and lines - with ``#`` as the first non-blank character are omitted.""" - - def metadata_isdir(name): - """Is the named metadata a directory? (like ``os.path.isdir()``)""" - - def metadata_listdir(name): - """List of metadata names in the directory (like ``os.listdir()``)""" - - def run_script(script_name, namespace): - """Execute the named script in the supplied namespace dictionary""" - - -class IResourceProvider(IMetadataProvider): - """An object that provides access to package resources""" - - def get_resource_filename(manager, resource_name): - """Return a true filesystem path for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_stream(manager, resource_name): - """Return a readable file-like object for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_string(manager, resource_name): - """Return a string containing the contents of `resource_name` - - `manager` must be an ``IResourceManager``""" - - def has_resource(resource_name): - """Does the package contain the named resource?""" - - def resource_isdir(resource_name): - """Is the named resource a directory? (like ``os.path.isdir()``)""" - - def resource_listdir(resource_name): - """List of resource names in the directory (like ``os.listdir()``)""" - - -class WorkingSet: - """A collection of active distributions on sys.path (or a similar list)""" - - def __init__(self, entries=None): - """Create working set from list of path entries (default=sys.path)""" - self.entries = [] - self.entry_keys = {} - self.by_key = {} - self.callbacks = [] - - if entries is None: - entries = sys.path - - for entry in entries: - self.add_entry(entry) - - @classmethod - def _build_master(cls): - """ - Prepare the master working set. - """ - ws = cls() - try: - from __main__ import __requires__ - except ImportError: - # The main program does not list any requirements - return ws - - # ensure the requirements are met - try: - ws.require(__requires__) - except VersionConflict: - return cls._build_from_requirements(__requires__) - - return ws - - @classmethod - def _build_from_requirements(cls, req_spec): - """ - Build a working set from a requirement spec. Rewrites sys.path. - """ - # try it without defaults already on sys.path - # by starting with an empty path - ws = cls([]) - reqs = parse_requirements(req_spec) - dists = ws.resolve(reqs, Environment()) - for dist in dists: - ws.add(dist) - - # add any missing entries from sys.path - for entry in sys.path: - if entry not in ws.entries: - ws.add_entry(entry) - - # then copy back to sys.path - sys.path[:] = ws.entries - return ws - - def add_entry(self, entry): - """Add a path item to ``.entries``, finding any distributions on it - - ``find_distributions(entry, True)`` is used to find distributions - corresponding to the path entry, and they are added. `entry` is - always appended to ``.entries``, even if it is already present. - (This is because ``sys.path`` can contain the same value more than - once, and the ``.entries`` of the ``sys.path`` WorkingSet should always - equal ``sys.path``.) - """ - self.entry_keys.setdefault(entry, []) - self.entries.append(entry) - for dist in find_distributions(entry, True): - self.add(dist, entry, False) - - def __contains__(self, dist): - """True if `dist` is the active distribution for its project""" - return self.by_key.get(dist.key) == dist - - def find(self, req): - """Find a distribution matching requirement `req` - - If there is an active distribution for the requested project, this - returns it as long as it meets the version requirement specified by - `req`. But, if there is an active distribution for the project and it - does *not* meet the `req` requirement, ``VersionConflict`` is raised. - If there is no active distribution for the requested project, ``None`` - is returned. - """ - dist = self.by_key.get(req.key) - if dist is not None and dist not in req: - # XXX add more info - raise VersionConflict(dist, req) - return dist - - def iter_entry_points(self, group, name=None): - """Yield entry point objects from `group` matching `name` - - If `name` is None, yields all entry points in `group` from all - distributions in the working set, otherwise only ones matching - both `group` and `name` are yielded (in distribution order). - """ - return ( - entry - for dist in self - for entry in dist.get_entry_map(group).values() - if name is None or name == entry.name - ) - - def run_script(self, requires, script_name): - """Locate distribution for `requires` and run `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - self.require(requires)[0].run_script(script_name, ns) - - def __iter__(self): - """Yield distributions for non-duplicate projects in the working set - - The yield order is the order in which the items' path entries were - added to the working set. - """ - seen = {} - for item in self.entries: - if item not in self.entry_keys: - # workaround a cache issue - continue - - for key in self.entry_keys[item]: - if key not in seen: - seen[key] = 1 - yield self.by_key[key] - - def add(self, dist, entry=None, insert=True, replace=False): - """Add `dist` to working set, associated with `entry` - - If `entry` is unspecified, it defaults to the ``.location`` of `dist`. - On exit from this routine, `entry` is added to the end of the working - set's ``.entries`` (if it wasn't already present). - - `dist` is only added to the working set if it's for a project that - doesn't already have a distribution in the set, unless `replace=True`. - If it's added, any callbacks registered with the ``subscribe()`` method - will be called. - """ - if insert: - dist.insert_on(self.entries, entry, replace=replace) - - if entry is None: - entry = dist.location - keys = self.entry_keys.setdefault(entry, []) - keys2 = self.entry_keys.setdefault(dist.location, []) - if not replace and dist.key in self.by_key: - # ignore hidden distros - return - - self.by_key[dist.key] = dist - if dist.key not in keys: - keys.append(dist.key) - if dist.key not in keys2: - keys2.append(dist.key) - self._added_new(dist) - - def resolve(self, requirements, env=None, installer=None, - replace_conflicting=False, extras=None): - """List all distributions needed to (recursively) meet `requirements` - - `requirements` must be a sequence of ``Requirement`` objects. `env`, - if supplied, should be an ``Environment`` instance. If - not supplied, it defaults to all distributions available within any - entry or distribution in the working set. `installer`, if supplied, - will be invoked with each requirement that cannot be met by an - already-installed distribution; it should return a ``Distribution`` or - ``None``. - - Unless `replace_conflicting=True`, raises a VersionConflict exception - if - any requirements are found on the path that have the correct name but - the wrong version. Otherwise, if an `installer` is supplied it will be - invoked to obtain the correct version of the requirement and activate - it. - - `extras` is a list of the extras to be used with these requirements. - This is important because extra requirements may look like `my_req; - extra = "my_extra"`, which would otherwise be interpreted as a purely - optional requirement. Instead, we want to be able to assert that these - requirements are truly required. - """ - - # set up the stack - requirements = list(requirements)[::-1] - # set of processed requirements - processed = {} - # key -> dist - best = {} - to_activate = [] - - req_extras = _ReqExtras() - - # Mapping of requirement to set of distributions that required it; - # useful for reporting info about conflicts. - required_by = collections.defaultdict(set) - - while requirements: - # process dependencies breadth-first - req = requirements.pop(0) - if req in processed: - # Ignore cyclic or redundant dependencies - continue - - if not req_extras.markers_pass(req, extras): - continue - - dist = best.get(req.key) - if dist is None: - # Find the best distribution and add it to the map - dist = self.by_key.get(req.key) - if dist is None or (dist not in req and replace_conflicting): - ws = self - if env is None: - if dist is None: - env = Environment(self.entries) - else: - # Use an empty environment and workingset to avoid - # any further conflicts with the conflicting - # distribution - env = Environment([]) - ws = WorkingSet([]) - dist = best[req.key] = env.best_match( - req, ws, installer, - replace_conflicting=replace_conflicting - ) - if dist is None: - requirers = required_by.get(req, None) - raise DistributionNotFound(req, requirers) - to_activate.append(dist) - if dist not in req: - # Oops, the "best" so far conflicts with a dependency - dependent_req = required_by[req] - raise VersionConflict(dist, req).with_context(dependent_req) - - # push the new requirements onto the stack - new_requirements = dist.requires(req.extras)[::-1] - requirements.extend(new_requirements) - - # Register the new requirements needed by req - for new_requirement in new_requirements: - required_by[new_requirement].add(req.project_name) - req_extras[new_requirement] = req.extras - - processed[req] = True - - # return list of distros to activate - return to_activate - - def find_plugins( - self, plugin_env, full_env=None, installer=None, fallback=True): - """Find all activatable distributions in `plugin_env` - - Example usage:: - - distributions, errors = working_set.find_plugins( - Environment(plugin_dirlist) - ) - # add plugins+libs to sys.path - map(working_set.add, distributions) - # display errors - print('Could not load', errors) - - The `plugin_env` should be an ``Environment`` instance that contains - only distributions that are in the project's "plugin directory" or - directories. The `full_env`, if supplied, should be an ``Environment`` - contains all currently-available distributions. If `full_env` is not - supplied, one is created automatically from the ``WorkingSet`` this - method is called on, which will typically mean that every directory on - ``sys.path`` will be scanned for distributions. - - `installer` is a standard installer callback as used by the - ``resolve()`` method. The `fallback` flag indicates whether we should - attempt to resolve older versions of a plugin if the newest version - cannot be resolved. - - This method returns a 2-tuple: (`distributions`, `error_info`), where - `distributions` is a list of the distributions found in `plugin_env` - that were loadable, along with any other distributions that are needed - to resolve their dependencies. `error_info` is a dictionary mapping - unloadable plugin distributions to an exception instance describing the - error that occurred. Usually this will be a ``DistributionNotFound`` or - ``VersionConflict`` instance. - """ - - plugin_projects = list(plugin_env) - # scan project names in alphabetic order - plugin_projects.sort() - - error_info = {} - distributions = {} - - if full_env is None: - env = Environment(self.entries) - env += plugin_env - else: - env = full_env + plugin_env - - shadow_set = self.__class__([]) - # put all our entries in shadow_set - list(map(shadow_set.add, self)) - - for project_name in plugin_projects: - - for dist in plugin_env[project_name]: - - req = [dist.as_requirement()] - - try: - resolvees = shadow_set.resolve(req, env, installer) - - except ResolutionError as v: - # save error info - error_info[dist] = v - if fallback: - # try the next older version of project - continue - else: - # give up on this project, keep going - break - - else: - list(map(shadow_set.add, resolvees)) - distributions.update(dict.fromkeys(resolvees)) - - # success, no need to try any more versions of this project - break - - distributions = list(distributions) - distributions.sort() - - return distributions, error_info - - def require(self, *requirements): - """Ensure that distributions matching `requirements` are activated - - `requirements` must be a string or a (possibly-nested) sequence - thereof, specifying the distributions and versions required. The - return value is a sequence of the distributions that needed to be - activated to fulfill the requirements; all relevant distributions are - included, even if they were already activated in this working set. - """ - needed = self.resolve(parse_requirements(requirements)) - - for dist in needed: - self.add(dist) - - return needed - - def subscribe(self, callback, existing=True): - """Invoke `callback` for all distributions - - If `existing=True` (default), - call on all existing ones, as well. - """ - if callback in self.callbacks: - return - self.callbacks.append(callback) - if not existing: - return - for dist in self: - callback(dist) - - def _added_new(self, dist): - for callback in self.callbacks: - callback(dist) - - def __getstate__(self): - return ( - self.entries[:], self.entry_keys.copy(), self.by_key.copy(), - self.callbacks[:] - ) - - def __setstate__(self, e_k_b_c): - entries, keys, by_key, callbacks = e_k_b_c - self.entries = entries[:] - self.entry_keys = keys.copy() - self.by_key = by_key.copy() - self.callbacks = callbacks[:] - - -class _ReqExtras(dict): - """ - Map each requirement to the extras that demanded it. - """ - - def markers_pass(self, req, extras=None): - """ - Evaluate markers for req against each extra that - demanded it. - - Return False if the req has a marker and fails - evaluation. Otherwise, return True. - """ - extra_evals = ( - req.marker.evaluate({'extra': extra}) - for extra in self.get(req, ()) + (extras or (None,)) - ) - return not req.marker or any(extra_evals) - - -class Environment: - """Searchable snapshot of distributions on a search path""" - - def __init__( - self, search_path=None, platform=get_supported_platform(), - python=PY_MAJOR): - """Snapshot distributions available on a search path - - Any distributions found on `search_path` are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. - - `platform` is an optional string specifying the name of the platform - that platform-specific distributions must be compatible with. If - unspecified, it defaults to the current platform. `python` is an - optional string naming the desired version of Python (e.g. ``'3.6'``); - it defaults to the current version. - - You may explicitly set `platform` (and/or `python`) to ``None`` if you - wish to map *all* distributions, not just those compatible with the - running platform or Python version. - """ - self._distmap = {} - self.platform = platform - self.python = python - self.scan(search_path) - - def can_add(self, dist): - """Is distribution `dist` acceptable for this environment? - - The distribution must match the platform and python version - requirements specified when this environment was created, or False - is returned. - """ - py_compat = ( - self.python is None - or dist.py_version is None - or dist.py_version == self.python - ) - return py_compat and compatible_platforms(dist.platform, self.platform) - - def remove(self, dist): - """Remove `dist` from the environment""" - self._distmap[dist.key].remove(dist) - - def scan(self, search_path=None): - """Scan `search_path` for distributions usable in this environment - - Any distributions found are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. Only distributions conforming to - the platform/python version defined at initialization are added. - """ - if search_path is None: - search_path = sys.path - - for item in search_path: - for dist in find_distributions(item): - self.add(dist) - - def __getitem__(self, project_name): - """Return a newest-to-oldest list of distributions for `project_name` - - Uses case-insensitive `project_name` comparison, assuming all the - project's distributions use their project's name converted to all - lowercase as their key. - - """ - distribution_key = project_name.lower() - return self._distmap.get(distribution_key, []) - - def add(self, dist): - """Add `dist` if we ``can_add()`` it and it has not already been added - """ - if self.can_add(dist) and dist.has_version(): - dists = self._distmap.setdefault(dist.key, []) - if dist not in dists: - dists.append(dist) - dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) - - def best_match( - self, req, working_set, installer=None, replace_conflicting=False): - """Find distribution best matching `req` and usable on `working_set` - - This calls the ``find(req)`` method of the `working_set` to see if a - suitable distribution is already active. (This may raise - ``VersionConflict`` if an unsuitable version of the project is already - active in the specified `working_set`.) If a suitable distribution - isn't active, this method returns the newest distribution in the - environment that meets the ``Requirement`` in `req`. If no suitable - distribution is found, and `installer` is supplied, then the result of - calling the environment's ``obtain(req, installer)`` method will be - returned. - """ - try: - dist = working_set.find(req) - except VersionConflict: - if not replace_conflicting: - raise - dist = None - if dist is not None: - return dist - for dist in self[req.key]: - if dist in req: - return dist - # try to download/install - return self.obtain(req, installer) - - def obtain(self, requirement, installer=None): - """Obtain a distribution matching `requirement` (e.g. via download) - - Obtain a distro that matches requirement (e.g. via download). In the - base ``Environment`` class, this routine just returns - ``installer(requirement)``, unless `installer` is None, in which case - None is returned instead. This method is a hook that allows subclasses - to attempt other ways of obtaining a distribution before falling back - to the `installer` argument.""" - if installer is not None: - return installer(requirement) - - def __iter__(self): - """Yield the unique project names of the available distributions""" - for key in self._distmap.keys(): - if self[key]: - yield key - - def __iadd__(self, other): - """In-place addition of a distribution or environment""" - if isinstance(other, Distribution): - self.add(other) - elif isinstance(other, Environment): - for project in other: - for dist in other[project]: - self.add(dist) - else: - raise TypeError("Can't add %r to environment" % (other,)) - return self - - def __add__(self, other): - """Add an environment or distribution to an environment""" - new = self.__class__([], platform=None, python=None) - for env in self, other: - new += env - return new - - -# XXX backward compatibility -AvailableDistributions = Environment - - -class ExtractionError(RuntimeError): - """An error occurred extracting a resource - - The following attributes are available from instances of this exception: - - manager - The resource manager that raised this exception - - cache_path - The base directory for resource extraction - - original_error - The exception instance that caused extraction to fail - """ - - -class ResourceManager: - """Manage resource extraction and packages""" - extraction_path = None - - def __init__(self): - self.cached_files = {} - - def resource_exists(self, package_or_requirement, resource_name): - """Does the named resource exist?""" - return get_provider(package_or_requirement).has_resource(resource_name) - - def resource_isdir(self, package_or_requirement, resource_name): - """Is the named resource an existing directory?""" - return get_provider(package_or_requirement).resource_isdir( - resource_name - ) - - def resource_filename(self, package_or_requirement, resource_name): - """Return a true filesystem path for specified resource""" - return get_provider(package_or_requirement).get_resource_filename( - self, resource_name - ) - - def resource_stream(self, package_or_requirement, resource_name): - """Return a readable file-like object for specified resource""" - return get_provider(package_or_requirement).get_resource_stream( - self, resource_name - ) - - def resource_string(self, package_or_requirement, resource_name): - """Return specified resource as a string""" - return get_provider(package_or_requirement).get_resource_string( - self, resource_name - ) - - def resource_listdir(self, package_or_requirement, resource_name): - """List the contents of the named resource directory""" - return get_provider(package_or_requirement).resource_listdir( - resource_name - ) - - def extraction_error(self): - """Give an error message for problems extracting file(s)""" - - old_exc = sys.exc_info()[1] - cache_path = self.extraction_path or get_default_cache() - - tmpl = textwrap.dedent(""" - Can't extract file(s) to egg cache - - The following error occurred while trying to extract file(s) - to the Python egg cache: - - {old_exc} - - The Python egg cache directory is currently set to: - - {cache_path} - - Perhaps your account does not have write access to this directory? - You can change the cache directory by setting the PYTHON_EGG_CACHE - environment variable to point to an accessible directory. - """).lstrip() - err = ExtractionError(tmpl.format(**locals())) - err.manager = self - err.cache_path = cache_path - err.original_error = old_exc - raise err - - def get_cache_path(self, archive_name, names=()): - """Return absolute location in cache for `archive_name` and `names` - - The parent directory of the resulting path will be created if it does - not already exist. `archive_name` should be the base filename of the - enclosing egg (which may not be the name of the enclosing zipfile!), - including its ".egg" extension. `names`, if provided, should be a - sequence of path name parts "under" the egg's extraction location. - - This method should only be called by resource providers that need to - obtain an extraction location, and only for names they intend to - extract, as it tracks the generated names for possible cleanup later. - """ - extract_path = self.extraction_path or get_default_cache() - target_path = os.path.join(extract_path, archive_name + '-tmp', *names) - try: - _bypass_ensure_directory(target_path) - except Exception: - self.extraction_error() - - self._warn_unsafe_extraction_path(extract_path) - - self.cached_files[target_path] = 1 - return target_path - - @staticmethod - def _warn_unsafe_extraction_path(path): - """ - If the default extraction path is overridden and set to an insecure - location, such as /tmp, it opens up an opportunity for an attacker to - replace an extracted file with an unauthorized payload. Warn the user - if a known insecure location is used. - - See Distribute #375 for more details. - """ - if os.name == 'nt' and not path.startswith(os.environ['windir']): - # On Windows, permissions are generally restrictive by default - # and temp directories are not writable by other users, so - # bypass the warning. - return - mode = os.stat(path).st_mode - if mode & stat.S_IWOTH or mode & stat.S_IWGRP: - msg = ( - "%s is writable by group/others and vulnerable to attack " - "when " - "used with get_resource_filename. Consider a more secure " - "location (set with .set_extraction_path or the " - "PYTHON_EGG_CACHE environment variable)." % path - ) - warnings.warn(msg, UserWarning) - - def postprocess(self, tempname, filename): - """Perform any platform-specific postprocessing of `tempname` - - This is where Mac header rewrites should be done; other platforms don't - have anything special they should do. - - Resource providers should call this method ONLY after successfully - extracting a compressed resource. They must NOT call it on resources - that are already in the filesystem. - - `tempname` is the current (temporary) name of the file, and `filename` - is the name it will be renamed to by the caller after this routine - returns. - """ - - if os.name == 'posix': - # Make the resource executable - mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 - os.chmod(tempname, mode) - - def set_extraction_path(self, path): - """Set the base path where resources will be extracted to, if needed. - - If you do not call this routine before any extractions take place, the - path defaults to the return value of ``get_default_cache()``. (Which - is based on the ``PYTHON_EGG_CACHE`` environment variable, with various - platform-specific fallbacks. See that routine's documentation for more - details.) - - Resources are extracted to subdirectories of this path based upon - information given by the ``IResourceProvider``. You may set this to a - temporary directory, but then you must call ``cleanup_resources()`` to - delete the extracted files when done. There is no guarantee that - ``cleanup_resources()`` will be able to remove all extracted files. - - (Note: you may not change the extraction path for a given resource - manager once resources have been extracted, unless you first call - ``cleanup_resources()``.) - """ - if self.cached_files: - raise ValueError( - "Can't change extraction path, files already extracted" - ) - - self.extraction_path = path - - def cleanup_resources(self, force=False): - """ - Delete all extracted resource files and directories, returning a list - of the file and directory names that could not be successfully removed. - This function does not have any concurrency protection, so it should - generally only be called when the extraction path is a temporary - directory exclusive to a single process. This method is not - automatically called; you must call it explicitly or register it as an - ``atexit`` function if you wish to ensure cleanup of a temporary - directory used for extractions. - """ - # XXX - - -def get_default_cache(): - """ - Return the ``PYTHON_EGG_CACHE`` environment variable - or a platform-relevant user cache dir for an app - named "Python-Eggs". - """ - return ( - os.environ.get('PYTHON_EGG_CACHE') - or appdirs.user_cache_dir(appname='Python-Eggs') - ) - - -def safe_name(name): - """Convert an arbitrary string to a standard distribution name - - Any runs of non-alphanumeric/. characters are replaced with a single '-'. - """ - return re.sub('[^A-Za-z0-9.]+', '-', name) - - -def safe_version(version): - """ - Convert an arbitrary string to a standard version string - """ - try: - # normalize the version - return str(packaging.version.Version(version)) - except packaging.version.InvalidVersion: - version = version.replace(' ', '.') - return re.sub('[^A-Za-z0-9.]+', '-', version) - - -def safe_extra(extra): - """Convert an arbitrary string to a standard 'extra' name - - Any runs of non-alphanumeric characters are replaced with a single '_', - and the result is always lowercased. - """ - return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() - - -def to_filename(name): - """Convert a project or version name to its filename-escaped form - - Any '-' characters are currently replaced with '_'. - """ - return name.replace('-', '_') - - -def invalid_marker(text): - """ - Validate text as a PEP 508 environment marker; return an exception - if invalid or False otherwise. - """ - try: - evaluate_marker(text) - except SyntaxError as e: - e.filename = None - e.lineno = None - return e - return False - - -def evaluate_marker(text, extra=None): - """ - Evaluate a PEP 508 environment marker. - Return a boolean indicating the marker result in this environment. - Raise SyntaxError if marker is invalid. - - This implementation uses the 'pyparsing' module. - """ - try: - marker = packaging.markers.Marker(text) - return marker.evaluate() - except packaging.markers.InvalidMarker as e: - raise SyntaxError(e) - - -class NullProvider: - """Try to implement resources and metadata for arbitrary PEP 302 loaders""" - - egg_name = None - egg_info = None - loader = None - - def __init__(self, module): - self.loader = getattr(module, '__loader__', None) - self.module_path = os.path.dirname(getattr(module, '__file__', '')) - - def get_resource_filename(self, manager, resource_name): - return self._fn(self.module_path, resource_name) - - def get_resource_stream(self, manager, resource_name): - return io.BytesIO(self.get_resource_string(manager, resource_name)) - - def get_resource_string(self, manager, resource_name): - return self._get(self._fn(self.module_path, resource_name)) - - def has_resource(self, resource_name): - return self._has(self._fn(self.module_path, resource_name)) - - def _get_metadata_path(self, name): - return self._fn(self.egg_info, name) - - def has_metadata(self, name): - if not self.egg_info: - return self.egg_info - - path = self._get_metadata_path(name) - return self._has(path) - - def get_metadata(self, name): - if not self.egg_info: - return "" - path = self._get_metadata_path(name) - value = self._get(path) - if six.PY2: - return value - try: - return value.decode('utf-8') - except UnicodeDecodeError as exc: - # Include the path in the error message to simplify - # troubleshooting, and without changing the exception type. - exc.reason += ' in {} file at path: {}'.format(name, path) - raise - - def get_metadata_lines(self, name): - return yield_lines(self.get_metadata(name)) - - def resource_isdir(self, resource_name): - return self._isdir(self._fn(self.module_path, resource_name)) - - def metadata_isdir(self, name): - return self.egg_info and self._isdir(self._fn(self.egg_info, name)) - - def resource_listdir(self, resource_name): - return self._listdir(self._fn(self.module_path, resource_name)) - - def metadata_listdir(self, name): - if self.egg_info: - return self._listdir(self._fn(self.egg_info, name)) - return [] - - def run_script(self, script_name, namespace): - script = 'scripts/' + script_name - if not self.has_metadata(script): - raise ResolutionError( - "Script {script!r} not found in metadata at {self.egg_info!r}" - .format(**locals()), - ) - script_text = self.get_metadata(script).replace('\r\n', '\n') - script_text = script_text.replace('\r', '\n') - script_filename = self._fn(self.egg_info, script) - namespace['__file__'] = script_filename - if os.path.exists(script_filename): - source = open(script_filename).read() - code = compile(source, script_filename, 'exec') - exec(code, namespace, namespace) - else: - from linecache import cache - cache[script_filename] = ( - len(script_text), 0, script_text.split('\n'), script_filename - ) - script_code = compile(script_text, script_filename, 'exec') - exec(script_code, namespace, namespace) - - def _has(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _isdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _listdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _fn(self, base, resource_name): - self._validate_resource_path(resource_name) - if resource_name: - return os.path.join(base, *resource_name.split('/')) - return base - - @staticmethod - def _validate_resource_path(path): - """ - Validate the resource paths according to the docs. - https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access - - >>> warned = getfixture('recwarn') - >>> warnings.simplefilter('always') - >>> vrp = NullProvider._validate_resource_path - >>> vrp('foo/bar.txt') - >>> bool(warned) - False - >>> vrp('../foo/bar.txt') - >>> bool(warned) - True - >>> warned.clear() - >>> vrp('/foo/bar.txt') - >>> bool(warned) - True - >>> vrp('foo/../../bar.txt') - >>> bool(warned) - True - >>> warned.clear() - >>> vrp('foo/f../bar.txt') - >>> bool(warned) - False - - Windows path separators are straight-up disallowed. - >>> vrp(r'\\foo/bar.txt') - Traceback (most recent call last): - ... - ValueError: Use of .. or absolute path in a resource path \ -is not allowed. - - >>> vrp(r'C:\\foo/bar.txt') - Traceback (most recent call last): - ... - ValueError: Use of .. or absolute path in a resource path \ -is not allowed. - - Blank values are allowed - - >>> vrp('') - >>> bool(warned) - False - - Non-string values are not. - - >>> vrp(None) - Traceback (most recent call last): - ... - AttributeError: ... - """ - invalid = ( - os.path.pardir in path.split(posixpath.sep) or - posixpath.isabs(path) or - ntpath.isabs(path) - ) - if not invalid: - return - - msg = "Use of .. or absolute path in a resource path is not allowed." - - # Aggressively disallow Windows absolute paths - if ntpath.isabs(path) and not posixpath.isabs(path): - raise ValueError(msg) - - # for compatibility, warn; in future - # raise ValueError(msg) - warnings.warn( - msg[:-1] + " and will raise exceptions in a future release.", - DeprecationWarning, - stacklevel=4, - ) - - def _get(self, path): - if hasattr(self.loader, 'get_data'): - return self.loader.get_data(path) - raise NotImplementedError( - "Can't perform this operation for loaders without 'get_data()'" - ) - - -register_loader_type(object, NullProvider) - - -class EggProvider(NullProvider): - """Provider based on a virtual filesystem""" - - def __init__(self, module): - NullProvider.__init__(self, module) - self._setup_prefix() - - def _setup_prefix(self): - # we assume here that our metadata may be nested inside a "basket" - # of multiple eggs; that's why we use module_path instead of .archive - path = self.module_path - old = None - while path != old: - if _is_egg_path(path): - self.egg_name = os.path.basename(path) - self.egg_info = os.path.join(path, 'EGG-INFO') - self.egg_root = path - break - old = path - path, base = os.path.split(path) - - -class DefaultProvider(EggProvider): - """Provides access to package resources in the filesystem""" - - def _has(self, path): - return os.path.exists(path) - - def _isdir(self, path): - return os.path.isdir(path) - - def _listdir(self, path): - return os.listdir(path) - - def get_resource_stream(self, manager, resource_name): - return open(self._fn(self.module_path, resource_name), 'rb') - - def _get(self, path): - with open(path, 'rb') as stream: - return stream.read() - - @classmethod - def _register(cls): - loader_names = 'SourceFileLoader', 'SourcelessFileLoader', - for name in loader_names: - loader_cls = getattr(importlib_machinery, name, type(None)) - register_loader_type(loader_cls, cls) - - -DefaultProvider._register() - - -class EmptyProvider(NullProvider): - """Provider that returns nothing for all requests""" - - module_path = None - - _isdir = _has = lambda self, path: False - - def _get(self, path): - return '' - - def _listdir(self, path): - return [] - - def __init__(self): - pass - - -empty_provider = EmptyProvider() - - -class ZipManifests(dict): - """ - zip manifest builder - """ - - @classmethod - def build(cls, path): - """ - Build a dictionary similar to the zipimport directory - caches, except instead of tuples, store ZipInfo objects. - - Use a platform-specific path separator (os.sep) for the path keys - for compatibility with pypy on Windows. - """ - with zipfile.ZipFile(path) as zfile: - items = ( - ( - name.replace('/', os.sep), - zfile.getinfo(name), - ) - for name in zfile.namelist() - ) - return dict(items) - - load = build - - -class MemoizedZipManifests(ZipManifests): - """ - Memoized zipfile manifests. - """ - manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') - - def load(self, path): - """ - Load a manifest at path or return a suitable manifest already loaded. - """ - path = os.path.normpath(path) - mtime = os.stat(path).st_mtime - - if path not in self or self[path].mtime != mtime: - manifest = self.build(path) - self[path] = self.manifest_mod(manifest, mtime) - - return self[path].manifest - - -class ZipProvider(EggProvider): - """Resource support for zips and eggs""" - - eagers = None - _zip_manifests = MemoizedZipManifests() - - def __init__(self, module): - EggProvider.__init__(self, module) - self.zip_pre = self.loader.archive + os.sep - - def _zipinfo_name(self, fspath): - # Convert a virtual filename (full path to file) into a zipfile subpath - # usable with the zipimport directory cache for our target archive - fspath = fspath.rstrip(os.sep) - if fspath == self.loader.archive: - return '' - if fspath.startswith(self.zip_pre): - return fspath[len(self.zip_pre):] - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.zip_pre) - ) - - def _parts(self, zip_path): - # Convert a zipfile subpath into an egg-relative path part list. - # pseudo-fs path - fspath = self.zip_pre + zip_path - if fspath.startswith(self.egg_root + os.sep): - return fspath[len(self.egg_root) + 1:].split(os.sep) - raise AssertionError( - "%s is not a subpath of %s" % (fspath, self.egg_root) - ) - - @property - def zipinfo(self): - return self._zip_manifests.load(self.loader.archive) - - def get_resource_filename(self, manager, resource_name): - if not self.egg_name: - raise NotImplementedError( - "resource_filename() only supported for .egg, not .zip" - ) - # no need to lock for extraction, since we use temp names - zip_path = self._resource_to_zip(resource_name) - eagers = self._get_eager_resources() - if '/'.join(self._parts(zip_path)) in eagers: - for name in eagers: - self._extract_resource(manager, self._eager_to_zip(name)) - return self._extract_resource(manager, zip_path) - - @staticmethod - def _get_date_and_size(zip_stat): - size = zip_stat.file_size - # ymdhms+wday, yday, dst - date_time = zip_stat.date_time + (0, 0, -1) - # 1980 offset already done - timestamp = time.mktime(date_time) - return timestamp, size - - def _extract_resource(self, manager, zip_path): - - if zip_path in self._index(): - for name in self._index()[zip_path]: - last = self._extract_resource( - manager, os.path.join(zip_path, name) - ) - # return the extracted directory name - return os.path.dirname(last) - - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - - if not WRITE_SUPPORT: - raise IOError('"os.rename" and "os.unlink" are not supported ' - 'on this platform') - try: - - real_path = manager.get_cache_path( - self.egg_name, self._parts(zip_path) - ) - - if self._is_current(real_path, zip_path): - return real_path - - outf, tmpnam = _mkstemp( - ".$extract", - dir=os.path.dirname(real_path), - ) - os.write(outf, self.loader.get_data(zip_path)) - os.close(outf) - utime(tmpnam, (timestamp, timestamp)) - manager.postprocess(tmpnam, real_path) - - try: - rename(tmpnam, real_path) - - except os.error: - if os.path.isfile(real_path): - if self._is_current(real_path, zip_path): - # the file became current since it was checked above, - # so proceed. - return real_path - # Windows, del old file and retry - elif os.name == 'nt': - unlink(real_path) - rename(tmpnam, real_path) - return real_path - raise - - except os.error: - # report a user-friendly error - manager.extraction_error() - - return real_path - - def _is_current(self, file_path, zip_path): - """ - Return True if the file_path is current for this zip_path - """ - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - if not os.path.isfile(file_path): - return False - stat = os.stat(file_path) - if stat.st_size != size or stat.st_mtime != timestamp: - return False - # check that the contents match - zip_contents = self.loader.get_data(zip_path) - with open(file_path, 'rb') as f: - file_contents = f.read() - return zip_contents == file_contents - - def _get_eager_resources(self): - if self.eagers is None: - eagers = [] - for name in ('native_libs.txt', 'eager_resources.txt'): - if self.has_metadata(name): - eagers.extend(self.get_metadata_lines(name)) - self.eagers = eagers - return self.eagers - - def _index(self): - try: - return self._dirindex - except AttributeError: - ind = {} - for path in self.zipinfo: - parts = path.split(os.sep) - while parts: - parent = os.sep.join(parts[:-1]) - if parent in ind: - ind[parent].append(parts[-1]) - break - else: - ind[parent] = [parts.pop()] - self._dirindex = ind - return ind - - def _has(self, fspath): - zip_path = self._zipinfo_name(fspath) - return zip_path in self.zipinfo or zip_path in self._index() - - def _isdir(self, fspath): - return self._zipinfo_name(fspath) in self._index() - - def _listdir(self, fspath): - return list(self._index().get(self._zipinfo_name(fspath), ())) - - def _eager_to_zip(self, resource_name): - return self._zipinfo_name(self._fn(self.egg_root, resource_name)) - - def _resource_to_zip(self, resource_name): - return self._zipinfo_name(self._fn(self.module_path, resource_name)) - - -register_loader_type(zipimport.zipimporter, ZipProvider) - - -class FileMetadata(EmptyProvider): - """Metadata handler for standalone PKG-INFO files - - Usage:: - - metadata = FileMetadata("/path/to/PKG-INFO") - - This provider rejects all data and metadata requests except for PKG-INFO, - which is treated as existing, and will be the contents of the file at - the provided location. - """ - - def __init__(self, path): - self.path = path - - def _get_metadata_path(self, name): - return self.path - - def has_metadata(self, name): - return name == 'PKG-INFO' and os.path.isfile(self.path) - - def get_metadata(self, name): - if name != 'PKG-INFO': - raise KeyError("No metadata except PKG-INFO is available") - - with io.open(self.path, encoding='utf-8', errors="replace") as f: - metadata = f.read() - self._warn_on_replacement(metadata) - return metadata - - def _warn_on_replacement(self, metadata): - # Python 2.7 compat for: replacement_char = '�' - replacement_char = b'\xef\xbf\xbd'.decode('utf-8') - if replacement_char in metadata: - tmpl = "{self.path} could not be properly decoded in UTF-8" - msg = tmpl.format(**locals()) - warnings.warn(msg) - - def get_metadata_lines(self, name): - return yield_lines(self.get_metadata(name)) - - -class PathMetadata(DefaultProvider): - """Metadata provider for egg directories - - Usage:: - - # Development eggs: - - egg_info = "/path/to/PackageName.egg-info" - base_dir = os.path.dirname(egg_info) - metadata = PathMetadata(base_dir, egg_info) - dist_name = os.path.splitext(os.path.basename(egg_info))[0] - dist = Distribution(basedir, project_name=dist_name, metadata=metadata) - - # Unpacked egg directories: - - egg_path = "/path/to/PackageName-ver-pyver-etc.egg" - metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) - dist = Distribution.from_filename(egg_path, metadata=metadata) - """ - - def __init__(self, path, egg_info): - self.module_path = path - self.egg_info = egg_info - - -class EggMetadata(ZipProvider): - """Metadata provider for .egg files""" - - def __init__(self, importer): - """Create a metadata provider from a zipimporter""" - - self.zip_pre = importer.archive + os.sep - self.loader = importer - if importer.prefix: - self.module_path = os.path.join(importer.archive, importer.prefix) - else: - self.module_path = importer.archive - self._setup_prefix() - - -_declare_state('dict', _distribution_finders={}) - - -def register_finder(importer_type, distribution_finder): - """Register `distribution_finder` to find distributions in sys.path items - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `distribution_finder` is a callable that, passed a path - item and the importer instance, yields ``Distribution`` instances found on - that path item. See ``pkg_resources.find_on_path`` for an example.""" - _distribution_finders[importer_type] = distribution_finder - - -def find_distributions(path_item, only=False): - """Yield distributions accessible via `path_item`""" - importer = get_importer(path_item) - finder = _find_adapter(_distribution_finders, importer) - return finder(importer, path_item, only) - - -def find_eggs_in_zip(importer, path_item, only=False): - """ - Find eggs in zip files; possibly multiple nested eggs. - """ - if importer.archive.endswith('.whl'): - # wheels are not supported with this finder - # they don't have PKG-INFO metadata, and won't ever contain eggs - return - metadata = EggMetadata(importer) - if metadata.has_metadata('PKG-INFO'): - yield Distribution.from_filename(path_item, metadata=metadata) - if only: - # don't yield nested distros - return - for subitem in metadata.resource_listdir(''): - if _is_egg_path(subitem): - subpath = os.path.join(path_item, subitem) - dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) - for dist in dists: - yield dist - elif subitem.lower().endswith('.dist-info'): - subpath = os.path.join(path_item, subitem) - submeta = EggMetadata(zipimport.zipimporter(subpath)) - submeta.egg_info = subpath - yield Distribution.from_location(path_item, subitem, submeta) - - -register_finder(zipimport.zipimporter, find_eggs_in_zip) - - -def find_nothing(importer, path_item, only=False): - return () - - -register_finder(object, find_nothing) - - -def _by_version_descending(names): - """ - Given a list of filenames, return them in descending order - by version number. - - >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' - >>> _by_version_descending(names) - ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] - >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' - >>> _by_version_descending(names) - ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] - """ - def _by_version(name): - """ - Parse each component of the filename - """ - name, ext = os.path.splitext(name) - parts = itertools.chain(name.split('-'), [ext]) - return [packaging.version.parse(part) for part in parts] - - return sorted(names, key=_by_version, reverse=True) - - -def find_on_path(importer, path_item, only=False): - """Yield distributions accessible on a sys.path directory""" - path_item = _normalize_cached(path_item) - - if _is_unpacked_egg(path_item): - yield Distribution.from_filename( - path_item, metadata=PathMetadata( - path_item, os.path.join(path_item, 'EGG-INFO') - ) - ) - return - - entries = safe_listdir(path_item) - - # for performance, before sorting by version, - # screen entries for only those that will yield - # distributions - filtered = ( - entry - for entry in entries - if dist_factory(path_item, entry, only) - ) - - # scan for .egg and .egg-info in directory - path_item_entries = _by_version_descending(filtered) - for entry in path_item_entries: - fullpath = os.path.join(path_item, entry) - factory = dist_factory(path_item, entry, only) - for dist in factory(fullpath): - yield dist - - -def dist_factory(path_item, entry, only): - """ - Return a dist_factory for a path_item and entry - """ - lower = entry.lower() - is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) - return ( - distributions_from_metadata - if is_meta else - find_distributions - if not only and _is_egg_path(entry) else - resolve_egg_link - if not only and lower.endswith('.egg-link') else - NoDists() - ) - - -class NoDists: - """ - >>> bool(NoDists()) - False - - >>> list(NoDists()('anything')) - [] - """ - def __bool__(self): - return False - if six.PY2: - __nonzero__ = __bool__ - - def __call__(self, fullpath): - return iter(()) - - -def safe_listdir(path): - """ - Attempt to list contents of path, but suppress some exceptions. - """ - try: - return os.listdir(path) - except (PermissionError, NotADirectoryError): - pass - except OSError as e: - # Ignore the directory if does not exist, not a directory or - # permission denied - ignorable = ( - e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) - # Python 2 on Windows needs to be handled this way :( - or getattr(e, "winerror", None) == 267 - ) - if not ignorable: - raise - return () - - -def distributions_from_metadata(path): - root = os.path.dirname(path) - if os.path.isdir(path): - if len(os.listdir(path)) == 0: - # empty metadata dir; skip - return - metadata = PathMetadata(root, path) - else: - metadata = FileMetadata(path) - entry = os.path.basename(path) - yield Distribution.from_location( - root, entry, metadata, precedence=DEVELOP_DIST, - ) - - -def non_empty_lines(path): - """ - Yield non-empty lines from file at path - """ - with open(path) as f: - for line in f: - line = line.strip() - if line: - yield line - - -def resolve_egg_link(path): - """ - Given a path to an .egg-link, resolve distributions - present in the referenced path. - """ - referenced_paths = non_empty_lines(path) - resolved_paths = ( - os.path.join(os.path.dirname(path), ref) - for ref in referenced_paths - ) - dist_groups = map(find_distributions, resolved_paths) - return next(dist_groups, ()) - - -register_finder(pkgutil.ImpImporter, find_on_path) - -if hasattr(importlib_machinery, 'FileFinder'): - register_finder(importlib_machinery.FileFinder, find_on_path) - -_declare_state('dict', _namespace_handlers={}) -_declare_state('dict', _namespace_packages={}) - - -def register_namespace_handler(importer_type, namespace_handler): - """Register `namespace_handler` to declare namespace packages - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `namespace_handler` is a callable like this:: - - def namespace_handler(importer, path_entry, moduleName, module): - # return a path_entry to use for child packages - - Namespace handlers are only called if the importer object has already - agreed that it can handle the relevant path item, and they should only - return a subpath if the module __path__ does not already contain an - equivalent subpath. For an example namespace handler, see - ``pkg_resources.file_ns_handler``. - """ - _namespace_handlers[importer_type] = namespace_handler - - -def _handle_ns(packageName, path_item): - """Ensure that named package includes a subpath of path_item (if needed)""" - - importer = get_importer(path_item) - if importer is None: - return None - - # capture warnings due to #1111 - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - loader = importer.find_module(packageName) - - if loader is None: - return None - module = sys.modules.get(packageName) - if module is None: - module = sys.modules[packageName] = types.ModuleType(packageName) - module.__path__ = [] - _set_parent_ns(packageName) - elif not hasattr(module, '__path__'): - raise TypeError("Not a package:", packageName) - handler = _find_adapter(_namespace_handlers, importer) - subpath = handler(importer, path_item, packageName, module) - if subpath is not None: - path = module.__path__ - path.append(subpath) - loader.load_module(packageName) - _rebuild_mod_path(path, packageName, module) - return subpath - - -def _rebuild_mod_path(orig_path, package_name, module): - """ - Rebuild module.__path__ ensuring that all entries are ordered - corresponding to their sys.path order - """ - sys_path = [_normalize_cached(p) for p in sys.path] - - def safe_sys_path_index(entry): - """ - Workaround for #520 and #513. - """ - try: - return sys_path.index(entry) - except ValueError: - return float('inf') - - def position_in_sys_path(path): - """ - Return the ordinal of the path based on its position in sys.path - """ - path_parts = path.split(os.sep) - module_parts = package_name.count('.') + 1 - parts = path_parts[:-module_parts] - return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) - - new_path = sorted(orig_path, key=position_in_sys_path) - new_path = [_normalize_cached(p) for p in new_path] - - if isinstance(module.__path__, list): - module.__path__[:] = new_path - else: - module.__path__ = new_path - - -def declare_namespace(packageName): - """Declare that package 'packageName' is a namespace package""" - - _imp.acquire_lock() - try: - if packageName in _namespace_packages: - return - - path = sys.path - parent, _, _ = packageName.rpartition('.') - - if parent: - declare_namespace(parent) - if parent not in _namespace_packages: - __import__(parent) - try: - path = sys.modules[parent].__path__ - except AttributeError: - raise TypeError("Not a package:", parent) - - # Track what packages are namespaces, so when new path items are added, - # they can be updated - _namespace_packages.setdefault(parent or None, []).append(packageName) - _namespace_packages.setdefault(packageName, []) - - for path_item in path: - # Ensure all the parent's path items are reflected in the child, - # if they apply - _handle_ns(packageName, path_item) - - finally: - _imp.release_lock() - - -def fixup_namespace_packages(path_item, parent=None): - """Ensure that previously-declared namespace packages include path_item""" - _imp.acquire_lock() - try: - for package in _namespace_packages.get(parent, ()): - subpath = _handle_ns(package, path_item) - if subpath: - fixup_namespace_packages(subpath, package) - finally: - _imp.release_lock() - - -def file_ns_handler(importer, path_item, packageName, module): - """Compute an ns-package subpath for a filesystem or zipfile importer""" - - subpath = os.path.join(path_item, packageName.split('.')[-1]) - normalized = _normalize_cached(subpath) - for item in module.__path__: - if _normalize_cached(item) == normalized: - break - else: - # Only return the path if it's not already there - return subpath - - -register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) -register_namespace_handler(zipimport.zipimporter, file_ns_handler) - -if hasattr(importlib_machinery, 'FileFinder'): - register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) - - -def null_ns_handler(importer, path_item, packageName, module): - return None - - -register_namespace_handler(object, null_ns_handler) - - -def normalize_path(filename): - """Normalize a file/dir name for comparison purposes""" - return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) - - -def _cygwin_patch(filename): # pragma: nocover - """ - Contrary to POSIX 2008, on Cygwin, getcwd (3) contains - symlink components. Using - os.path.abspath() works around this limitation. A fix in os.getcwd() - would probably better, in Cygwin even more so, except - that this seems to be by design... - """ - return os.path.abspath(filename) if sys.platform == 'cygwin' else filename - - -def _normalize_cached(filename, _cache={}): - try: - return _cache[filename] - except KeyError: - _cache[filename] = result = normalize_path(filename) - return result - - -def _is_egg_path(path): - """ - Determine if given path appears to be an egg. - """ - return path.lower().endswith('.egg') - - -def _is_unpacked_egg(path): - """ - Determine if given path appears to be an unpacked egg. - """ - return ( - _is_egg_path(path) and - os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) - ) - - -def _set_parent_ns(packageName): - parts = packageName.split('.') - name = parts.pop() - if parts: - parent = '.'.join(parts) - setattr(sys.modules[parent], name, sys.modules[packageName]) - - -def yield_lines(strs): - """Yield non-empty/non-comment lines of a string or sequence""" - if isinstance(strs, six.string_types): - for s in strs.splitlines(): - s = s.strip() - # skip blank lines/comments - if s and not s.startswith('#'): - yield s - else: - for ss in strs: - for s in yield_lines(ss): - yield s - - -MODULE = re.compile(r"\w+(\.\w+)*$").match -EGG_NAME = re.compile( - r""" - (?P[^-]+) ( - -(?P[^-]+) ( - -py(?P[^-]+) ( - -(?P.+) - )? - )? - )? - """, - re.VERBOSE | re.IGNORECASE, -).match - - -class EntryPoint: - """Object representing an advertised importable object""" - - def __init__(self, name, module_name, attrs=(), extras=(), dist=None): - if not MODULE(module_name): - raise ValueError("Invalid module name", module_name) - self.name = name - self.module_name = module_name - self.attrs = tuple(attrs) - self.extras = tuple(extras) - self.dist = dist - - def __str__(self): - s = "%s = %s" % (self.name, self.module_name) - if self.attrs: - s += ':' + '.'.join(self.attrs) - if self.extras: - s += ' [%s]' % ','.join(self.extras) - return s - - def __repr__(self): - return "EntryPoint.parse(%r)" % str(self) - - def load(self, require=True, *args, **kwargs): - """ - Require packages for this EntryPoint, then resolve it. - """ - if not require or args or kwargs: - warnings.warn( - "Parameters to load are deprecated. Call .resolve and " - ".require separately.", - PkgResourcesDeprecationWarning, - stacklevel=2, - ) - if require: - self.require(*args, **kwargs) - return self.resolve() - - def resolve(self): - """ - Resolve the entry point from its module and attrs. - """ - module = __import__(self.module_name, fromlist=['__name__'], level=0) - try: - return functools.reduce(getattr, self.attrs, module) - except AttributeError as exc: - raise ImportError(str(exc)) - - def require(self, env=None, installer=None): - if self.extras and not self.dist: - raise UnknownExtra("Can't require() without a distribution", self) - - # Get the requirements for this entry point with all its extras and - # then resolve them. We have to pass `extras` along when resolving so - # that the working set knows what extras we want. Otherwise, for - # dist-info distributions, the working set will assume that the - # requirements for that extra are purely optional and skip over them. - reqs = self.dist.requires(self.extras) - items = working_set.resolve(reqs, env, installer, extras=self.extras) - list(map(working_set.add, items)) - - pattern = re.compile( - r'\s*' - r'(?P.+?)\s*' - r'=\s*' - r'(?P[\w.]+)\s*' - r'(:\s*(?P[\w.]+))?\s*' - r'(?P\[.*\])?\s*$' - ) - - @classmethod - def parse(cls, src, dist=None): - """Parse a single entry point from string `src` - - Entry point syntax follows the form:: - - name = some.module:some.attr [extra1, extra2] - - The entry name and module name are required, but the ``:attrs`` and - ``[extras]`` parts are optional - """ - m = cls.pattern.match(src) - if not m: - msg = "EntryPoint must be in 'name=module:attrs [extras]' format" - raise ValueError(msg, src) - res = m.groupdict() - extras = cls._parse_extras(res['extras']) - attrs = res['attr'].split('.') if res['attr'] else () - return cls(res['name'], res['module'], attrs, extras, dist) - - @classmethod - def _parse_extras(cls, extras_spec): - if not extras_spec: - return () - req = Requirement.parse('x' + extras_spec) - if req.specs: - raise ValueError() - return req.extras - - @classmethod - def parse_group(cls, group, lines, dist=None): - """Parse an entry point group""" - if not MODULE(group): - raise ValueError("Invalid group name", group) - this = {} - for line in yield_lines(lines): - ep = cls.parse(line, dist) - if ep.name in this: - raise ValueError("Duplicate entry point", group, ep.name) - this[ep.name] = ep - return this - - @classmethod - def parse_map(cls, data, dist=None): - """Parse a map of entry point groups""" - if isinstance(data, dict): - data = data.items() - else: - data = split_sections(data) - maps = {} - for group, lines in data: - if group is None: - if not lines: - continue - raise ValueError("Entry points must be listed in groups") - group = group.strip() - if group in maps: - raise ValueError("Duplicate group name", group) - maps[group] = cls.parse_group(group, lines, dist) - return maps - - -def _remove_md5_fragment(location): - if not location: - return '' - parsed = urllib.parse.urlparse(location) - if parsed[-1].startswith('md5='): - return urllib.parse.urlunparse(parsed[:-1] + ('',)) - return location - - -def _version_from_file(lines): - """ - Given an iterable of lines from a Metadata file, return - the value of the Version field, if present, or None otherwise. - """ - def is_version_line(line): - return line.lower().startswith('version:') - version_lines = filter(is_version_line, lines) - line = next(iter(version_lines), '') - _, _, value = line.partition(':') - return safe_version(value.strip()) or None - - -class Distribution: - """Wrap an actual or potential sys.path entry w/metadata""" - PKG_INFO = 'PKG-INFO' - - def __init__( - self, location=None, metadata=None, project_name=None, - version=None, py_version=PY_MAJOR, platform=None, - precedence=EGG_DIST): - self.project_name = safe_name(project_name or 'Unknown') - if version is not None: - self._version = safe_version(version) - self.py_version = py_version - self.platform = platform - self.location = location - self.precedence = precedence - self._provider = metadata or empty_provider - - @classmethod - def from_location(cls, location, basename, metadata=None, **kw): - project_name, version, py_version, platform = [None] * 4 - basename, ext = os.path.splitext(basename) - if ext.lower() in _distributionImpl: - cls = _distributionImpl[ext.lower()] - - match = EGG_NAME(basename) - if match: - project_name, version, py_version, platform = match.group( - 'name', 'ver', 'pyver', 'plat' - ) - return cls( - location, metadata, project_name=project_name, version=version, - py_version=py_version, platform=platform, **kw - )._reload_version() - - def _reload_version(self): - return self - - @property - def hashcmp(self): - return ( - self.parsed_version, - self.precedence, - self.key, - _remove_md5_fragment(self.location), - self.py_version or '', - self.platform or '', - ) - - def __hash__(self): - return hash(self.hashcmp) - - def __lt__(self, other): - return self.hashcmp < other.hashcmp - - def __le__(self, other): - return self.hashcmp <= other.hashcmp - - def __gt__(self, other): - return self.hashcmp > other.hashcmp - - def __ge__(self, other): - return self.hashcmp >= other.hashcmp - - def __eq__(self, other): - if not isinstance(other, self.__class__): - # It's not a Distribution, so they are not equal - return False - return self.hashcmp == other.hashcmp - - def __ne__(self, other): - return not self == other - - # These properties have to be lazy so that we don't have to load any - # metadata until/unless it's actually needed. (i.e., some distributions - # may not know their name or version without loading PKG-INFO) - - @property - def key(self): - try: - return self._key - except AttributeError: - self._key = key = self.project_name.lower() - return key - - @property - def parsed_version(self): - if not hasattr(self, "_parsed_version"): - self._parsed_version = parse_version(self.version) - - return self._parsed_version - - def _warn_legacy_version(self): - LV = packaging.version.LegacyVersion - is_legacy = isinstance(self._parsed_version, LV) - if not is_legacy: - return - - # While an empty version is technically a legacy version and - # is not a valid PEP 440 version, it's also unlikely to - # actually come from someone and instead it is more likely that - # it comes from setuptools attempting to parse a filename and - # including it in the list. So for that we'll gate this warning - # on if the version is anything at all or not. - if not self.version: - return - - tmpl = textwrap.dedent(""" - '{project_name} ({version})' is being parsed as a legacy, - non PEP 440, - version. You may find odd behavior and sort order. - In particular it will be sorted as less than 0.0. It - is recommended to migrate to PEP 440 compatible - versions. - """).strip().replace('\n', ' ') - - warnings.warn(tmpl.format(**vars(self)), PEP440Warning) - - @property - def version(self): - try: - return self._version - except AttributeError: - version = self._get_version() - if version is None: - path = self._get_metadata_path_for_display(self.PKG_INFO) - msg = ( - "Missing 'Version:' header and/or {} file at path: {}" - ).format(self.PKG_INFO, path) - raise ValueError(msg, self) - - return version - - @property - def _dep_map(self): - """ - A map of extra to its list of (direct) requirements - for this distribution, including the null extra. - """ - try: - return self.__dep_map - except AttributeError: - self.__dep_map = self._filter_extras(self._build_dep_map()) - return self.__dep_map - - @staticmethod - def _filter_extras(dm): - """ - Given a mapping of extras to dependencies, strip off - environment markers and filter out any dependencies - not matching the markers. - """ - for extra in list(filter(None, dm)): - new_extra = extra - reqs = dm.pop(extra) - new_extra, _, marker = extra.partition(':') - fails_marker = marker and ( - invalid_marker(marker) - or not evaluate_marker(marker) - ) - if fails_marker: - reqs = [] - new_extra = safe_extra(new_extra) or None - - dm.setdefault(new_extra, []).extend(reqs) - return dm - - def _build_dep_map(self): - dm = {} - for name in 'requires.txt', 'depends.txt': - for extra, reqs in split_sections(self._get_metadata(name)): - dm.setdefault(extra, []).extend(parse_requirements(reqs)) - return dm - - def requires(self, extras=()): - """List of Requirements needed for this distro if `extras` are used""" - dm = self._dep_map - deps = [] - deps.extend(dm.get(None, ())) - for ext in extras: - try: - deps.extend(dm[safe_extra(ext)]) - except KeyError: - raise UnknownExtra( - "%s has no such extra feature %r" % (self, ext) - ) - return deps - - def _get_metadata_path_for_display(self, name): - """ - Return the path to the given metadata file, if available. - """ - try: - # We need to access _get_metadata_path() on the provider object - # directly rather than through this class's __getattr__() - # since _get_metadata_path() is marked private. - path = self._provider._get_metadata_path(name) - - # Handle exceptions e.g. in case the distribution's metadata - # provider doesn't support _get_metadata_path(). - except Exception: - return '[could not detect]' - - return path - - def _get_metadata(self, name): - if self.has_metadata(name): - for line in self.get_metadata_lines(name): - yield line - - def _get_version(self): - lines = self._get_metadata(self.PKG_INFO) - version = _version_from_file(lines) - - return version - - def activate(self, path=None, replace=False): - """Ensure distribution is importable on `path` (default=sys.path)""" - if path is None: - path = sys.path - self.insert_on(path, replace=replace) - if path is sys.path: - fixup_namespace_packages(self.location) - for pkg in self._get_metadata('namespace_packages.txt'): - if pkg in sys.modules: - declare_namespace(pkg) - - def egg_name(self): - """Return what this distribution's standard .egg filename should be""" - filename = "%s-%s-py%s" % ( - to_filename(self.project_name), to_filename(self.version), - self.py_version or PY_MAJOR - ) - - if self.platform: - filename += '-' + self.platform - return filename - - def __repr__(self): - if self.location: - return "%s (%s)" % (self, self.location) - else: - return str(self) - - def __str__(self): - try: - version = getattr(self, 'version', None) - except ValueError: - version = None - version = version or "[unknown version]" - return "%s %s" % (self.project_name, version) - - def __getattr__(self, attr): - """Delegate all unrecognized public attributes to .metadata provider""" - if attr.startswith('_'): - raise AttributeError(attr) - return getattr(self._provider, attr) - - def __dir__(self): - return list( - set(super(Distribution, self).__dir__()) - | set( - attr for attr in self._provider.__dir__() - if not attr.startswith('_') - ) - ) - - if not hasattr(object, '__dir__'): - # python 2.7 not supported - del __dir__ - - @classmethod - def from_filename(cls, filename, metadata=None, **kw): - return cls.from_location( - _normalize_cached(filename), os.path.basename(filename), metadata, - **kw - ) - - def as_requirement(self): - """Return a ``Requirement`` that matches this distribution exactly""" - if isinstance(self.parsed_version, packaging.version.Version): - spec = "%s==%s" % (self.project_name, self.parsed_version) - else: - spec = "%s===%s" % (self.project_name, self.parsed_version) - - return Requirement.parse(spec) - - def load_entry_point(self, group, name): - """Return the `name` entry point of `group` or raise ImportError""" - ep = self.get_entry_info(group, name) - if ep is None: - raise ImportError("Entry point %r not found" % ((group, name),)) - return ep.load() - - def get_entry_map(self, group=None): - """Return the entry point map for `group`, or the full entry map""" - try: - ep_map = self._ep_map - except AttributeError: - ep_map = self._ep_map = EntryPoint.parse_map( - self._get_metadata('entry_points.txt'), self - ) - if group is not None: - return ep_map.get(group, {}) - return ep_map - - def get_entry_info(self, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return self.get_entry_map(group).get(name) - - def insert_on(self, path, loc=None, replace=False): - """Ensure self.location is on path - - If replace=False (default): - - If location is already in path anywhere, do nothing. - - Else: - - If it's an egg and its parent directory is on path, - insert just ahead of the parent. - - Else: add to the end of path. - If replace=True: - - If location is already on path anywhere (not eggs) - or higher priority than its parent (eggs) - do nothing. - - Else: - - If it's an egg and its parent directory is on path, - insert just ahead of the parent, - removing any lower-priority entries. - - Else: add it to the front of path. - """ - - loc = loc or self.location - if not loc: - return - - nloc = _normalize_cached(loc) - bdir = os.path.dirname(nloc) - npath = [(p and _normalize_cached(p) or p) for p in path] - - for p, item in enumerate(npath): - if item == nloc: - if replace: - break - else: - # don't modify path (even removing duplicates) if - # found and not replace - return - elif item == bdir and self.precedence == EGG_DIST: - # if it's an .egg, give it precedence over its directory - # UNLESS it's already been added to sys.path and replace=False - if (not replace) and nloc in npath[p:]: - return - if path is sys.path: - self.check_version_conflict() - path.insert(p, loc) - npath.insert(p, nloc) - break - else: - if path is sys.path: - self.check_version_conflict() - if replace: - path.insert(0, loc) - else: - path.append(loc) - return - - # p is the spot where we found or inserted loc; now remove duplicates - while True: - try: - np = npath.index(nloc, p + 1) - except ValueError: - break - else: - del npath[np], path[np] - # ha! - p = np - - return - - def check_version_conflict(self): - if self.key == 'setuptools': - # ignore the inevitable setuptools self-conflicts :( - return - - nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) - loc = normalize_path(self.location) - for modname in self._get_metadata('top_level.txt'): - if (modname not in sys.modules or modname in nsp - or modname in _namespace_packages): - continue - if modname in ('pkg_resources', 'setuptools', 'site'): - continue - fn = getattr(sys.modules[modname], '__file__', None) - if fn and (normalize_path(fn).startswith(loc) or - fn.startswith(self.location)): - continue - issue_warning( - "Module %s was already imported from %s, but %s is being added" - " to sys.path" % (modname, fn, self.location), - ) - - def has_version(self): - try: - self.version - except ValueError: - issue_warning("Unbuilt egg for " + repr(self)) - return False - return True - - def clone(self, **kw): - """Copy this distribution, substituting in any changed keyword args""" - names = 'project_name version py_version platform location precedence' - for attr in names.split(): - kw.setdefault(attr, getattr(self, attr, None)) - kw.setdefault('metadata', self._provider) - return self.__class__(**kw) - - @property - def extras(self): - return [dep for dep in self._dep_map if dep] - - -class EggInfoDistribution(Distribution): - def _reload_version(self): - """ - Packages installed by distutils (e.g. numpy or scipy), - which uses an old safe_version, and so - their version numbers can get mangled when - converted to filenames (e.g., 1.11.0.dev0+2329eae to - 1.11.0.dev0_2329eae). These distributions will not be - parsed properly - downstream by Distribution and safe_version, so - take an extra step and try to get the version number from - the metadata file itself instead of the filename. - """ - md_version = self._get_version() - if md_version: - self._version = md_version - return self - - -class DistInfoDistribution(Distribution): - """ - Wrap an actual or potential sys.path entry - w/metadata, .dist-info style. - """ - PKG_INFO = 'METADATA' - EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") - - @property - def _parsed_pkg_info(self): - """Parse and cache metadata""" - try: - return self._pkg_info - except AttributeError: - metadata = self.get_metadata(self.PKG_INFO) - self._pkg_info = email.parser.Parser().parsestr(metadata) - return self._pkg_info - - @property - def _dep_map(self): - try: - return self.__dep_map - except AttributeError: - self.__dep_map = self._compute_dependencies() - return self.__dep_map - - def _compute_dependencies(self): - """Recompute this distribution's dependencies.""" - dm = self.__dep_map = {None: []} - - reqs = [] - # Including any condition expressions - for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: - reqs.extend(parse_requirements(req)) - - def reqs_for_extra(extra): - for req in reqs: - if not req.marker or req.marker.evaluate({'extra': extra}): - yield req - - common = frozenset(reqs_for_extra(None)) - dm[None].extend(common) - - for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: - s_extra = safe_extra(extra.strip()) - dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) - - return dm - - -_distributionImpl = { - '.egg': Distribution, - '.egg-info': EggInfoDistribution, - '.dist-info': DistInfoDistribution, -} - - -def issue_warning(*args, **kw): - level = 1 - g = globals() - try: - # find the first stack frame that is *not* code in - # the pkg_resources module, to use for the warning - while sys._getframe(level).f_globals is g: - level += 1 - except ValueError: - pass - warnings.warn(stacklevel=level + 1, *args, **kw) - - -class RequirementParseError(ValueError): - def __str__(self): - return ' '.join(self.args) - - -def parse_requirements(strs): - """Yield ``Requirement`` objects for each specification in `strs` - - `strs` must be a string, or a (possibly-nested) iterable thereof. - """ - # create a steppable iterator, so we can handle \-continuations - lines = iter(yield_lines(strs)) - - for line in lines: - # Drop comments -- a hash without a space may be in a URL. - if ' #' in line: - line = line[:line.find(' #')] - # If there is a line continuation, drop it, and append the next line. - if line.endswith('\\'): - line = line[:-2].strip() - try: - line += next(lines) - except StopIteration: - return - yield Requirement(line) - - -class Requirement(packaging.requirements.Requirement): - def __init__(self, requirement_string): - """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" - try: - super(Requirement, self).__init__(requirement_string) - except packaging.requirements.InvalidRequirement as e: - raise RequirementParseError(str(e)) - self.unsafe_name = self.name - project_name = safe_name(self.name) - self.project_name, self.key = project_name, project_name.lower() - self.specs = [ - (spec.operator, spec.version) for spec in self.specifier] - self.extras = tuple(map(safe_extra, self.extras)) - self.hashCmp = ( - self.key, - self.url, - self.specifier, - frozenset(self.extras), - str(self.marker) if self.marker else None, - ) - self.__hash = hash(self.hashCmp) - - def __eq__(self, other): - return ( - isinstance(other, Requirement) and - self.hashCmp == other.hashCmp - ) - - def __ne__(self, other): - return not self == other - - def __contains__(self, item): - if isinstance(item, Distribution): - if item.key != self.key: - return False - - item = item.version - - # Allow prereleases always in order to match the previous behavior of - # this method. In the future this should be smarter and follow PEP 440 - # more accurately. - return self.specifier.contains(item, prereleases=True) - - def __hash__(self): - return self.__hash - - def __repr__(self): - return "Requirement.parse(%r)" % str(self) - - @staticmethod - def parse(s): - req, = parse_requirements(s) - return req - - -def _always_object(classes): - """ - Ensure object appears in the mro even - for old-style classes. - """ - if object not in classes: - return classes + (object,) - return classes - - -def _find_adapter(registry, ob): - """Return an adapter factory for `ob` from `registry`""" - types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) - for t in types: - if t in registry: - return registry[t] - - -def ensure_directory(path): - """Ensure that the parent directory of `path` exists""" - dirname = os.path.dirname(path) - py31compat.makedirs(dirname, exist_ok=True) - - -def _bypass_ensure_directory(path): - """Sandbox-bypassing version of ensure_directory()""" - if not WRITE_SUPPORT: - raise IOError('"os.mkdir" not supported on this platform.') - dirname, filename = split(path) - if dirname and filename and not isdir(dirname): - _bypass_ensure_directory(dirname) - try: - mkdir(dirname, 0o755) - except FileExistsError: - pass - - -def split_sections(s): - """Split a string or iterable thereof into (section, content) pairs - - Each ``section`` is a stripped version of the section header ("[section]") - and each ``content`` is a list of stripped lines excluding blank lines and - comment-only lines. If there are any such lines before the first section - header, they're returned in a first ``section`` of ``None``. - """ - section = None - content = [] - for line in yield_lines(s): - if line.startswith("["): - if line.endswith("]"): - if section or content: - yield section, content - section = line[1:-1].strip() - content = [] - else: - raise ValueError("Invalid section heading", line) - else: - content.append(line) - - # wrap up last segment - yield section, content - - -def _mkstemp(*args, **kw): - old_open = os.open - try: - # temporarily bypass sandboxing - os.open = os_open - return tempfile.mkstemp(*args, **kw) - finally: - # and then put it back - os.open = old_open - - -# Silence the PEP440Warning by default, so that end users don't get hit by it -# randomly just because they use pkg_resources. We want to append the rule -# because we want earlier uses of filterwarnings to take precedence over this -# one. -warnings.filterwarnings("ignore", category=PEP440Warning, append=True) - - -# from jaraco.functools 1.3 -def _call_aside(f, *args, **kwargs): - f(*args, **kwargs) - return f - - -@_call_aside -def _initialize(g=globals()): - "Set up global resource manager (deliberately not state-saved)" - manager = ResourceManager() - g['_manager'] = manager - g.update( - (name, getattr(manager, name)) - for name in dir(manager) - if not name.startswith('_') - ) - - -@_call_aside -def _initialize_master_working_set(): - """ - Prepare the master working set and make the ``require()`` - API available. - - This function has explicit effects on the global state - of pkg_resources. It is intended to be invoked once at - the initialization of this module. - - Invocation by other packages is unsupported and done - at their own risk. - """ - working_set = WorkingSet._build_master() - _declare_state('object', working_set=working_set) - - require = working_set.require - iter_entry_points = working_set.iter_entry_points - add_activation_listener = working_set.subscribe - run_script = working_set.run_script - # backward compatibility - run_main = run_script - # Activate all distributions already on sys.path with replace=False and - # ensure that all distributions added to the working set in the future - # (e.g. by calling ``require()``) will get activated as well, - # with higher priority (replace=True). - tuple( - dist.activate(replace=False) - for dist in working_set - ) - add_activation_listener( - lambda dist: dist.activate(replace=True), - existing=False, - ) - working_set.entries = [] - # match order - list(map(working_set.add_entry, sys.path)) - globals().update(locals()) - -class PkgResourcesDeprecationWarning(Warning): - """ - Base class for warning about deprecations in ``pkg_resources`` - - This class is not derived from ``DeprecationWarning``, and as such is - visible by default. - """ diff --git a/env/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 85b34fa73d8a31070a205fc910dc3d8552d645e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100402 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

    0~Fs% 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 OiqxcE`bWRi(*FT~!8yGE diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc deleted file mode 100644 index ba29b25065e887c8d9c843dd284914eaff5f7e5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201680 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 diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc deleted file mode 100644 index 953de53cf8a24199fdfd7341aff13fd48bfa4e99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24476 zcmb_^3z%F-b!PYNcTdk~JQ}_HY`-U^VhAB1k?byF2^*G8mJkva$Pxm9Bs>ywvn&JxSufdL60(Fi1n2)x z-Fv%xW@H}D%y;Xas(Y&H)TvXaPMxai2YP$65&Yfp){ht8JQIn0gOSd^-H7bM;~wdY zL{!9%sHn24(P_)JqJ(4Bm>rXM+>XmTVJGCBw3G5q*(nvb(<)(SoaAIyMb|}Ca>}xM z!dMEioQbLAYb<RB6;40GOPm3OE1f=j&{<`#2L2j*ZS8SqoxyM} z9kYnzq$V!|w9>g8czuF*#knh0=6qCt+UZx>g(z~}dmy5ERPL#W$~jjp#O!>l&$-&k zFGLoi(a3|5+LiH$bInxtY*Z(s5&j1`ACA8uuavsU6KDFYhh<&Z8KVdgR;a45=&ef0fEF!~tKeu2I*j>(tc?3B;~P>>720x?W;8s`dCb zq;8bhO^DsR5Chf*$+J;yko1Dug#TMqL1MQ`te|d{*k&nVi`p!)t!ll~d)Cr}>b9Dt zZdcocf;)h7r<8k_x?62mJ0vx)@(LVAZ9DP*GJ$rfT|Ts1?e?K9T{Y|x%J!-~Qr|vl z&3?5Hu^Z5m^$Ql>_oxH%zE>TT_si9N>JZAmK^<1Z>aalfs}c1IfsUx7>X<+esN?EE zfgVy1D_fvP)T8P#fnKSK>Qw@j)Tk;8q?Dt^1R7Tpsv^*&np9H)RaMo8rq#3$)l^N@ z>@;<3fsgr_nTFpvIOTAjnNy@x>TsH$7=(Xx; zbw;4qsh?A?7wG5J8`Luby-}T2ZxZOu>KD{o1o}nwta__JZ&SbIm;841%jzAH_ABb0 z>RkezQ|J9U-tFA1esxVm{hFlzJH-AyV*f#6??LRsnurM{<-O`Zs`m->>+1dLKMC|3 z>I3ROFT}=o+69c%E7S+4tg~@_#3`VE{)_s}1#3LIErM@_eUZmD+nbzQoQ=+=$y=RG z3o(qg&CVw0h6Uz0?rb=>#o45Oi(l77&O_^*jh{IF$R?Duv4{tB{MR)YxAs=S+^RlA z9E_IVRv*S_`LK+Z+aQ0xqdp?-8B)I+LcbS69}S`Z7D68jp^t>n$3y57A@utpv_rke zuj9Xm&?iIa4?^fuA@qkK^yv`#ObGo^Sn_8>=yM_T$07751{z;u-|pNFjt&Y(Z)^a1gf(sJs401305#p=Z1Zc{hMN9DYVy=y`ZfIz^%d0g6{+b?)bu}5{#PM4 zL+WcG^j9JDb<}CTej|kbI)uI%;(aTG{w9R}R|q{9LjOC2z8yk;8$$mlg#K>`{l5_U zP6+*72>pEseK&;uA%y;a2z@Vv{xO8UA42~WLeGcLKZmXSK?waz2>mdGUNF%3)%IP^ zU16`>+0iR0>HoW&JN;g{)4BOFn_9*dcZF`*mD`QU}61Rw6bibqxA5^UGwMyv)~gU2h*~rJZ~2gRn)efi3cK*diJItg%Iq`vyEWqSk}3M=aPQ2km=- zf1iC{7yc(h{Pn;e0{(qIK56}Xq}_z)W~3iNn-AN=h;6{L5h?dOSJ@-Aoro0z9K1K- zxdmT|c`F{lJU~g=jAx7RZ;RM1Bc#T;);Waqtqah|PU74voIU5G_7Q>h0y-+tK0wC= z+7IXff$jlxT%ZGh9t3Z*`im&(HaxeZ{)h11hUX5z5956&p1T0sc;Ag@JK#r<|53m@ zP{LzAyc6&%efVX7i?w6GU_S<>?gku`%6<$=Wp8$tN~(iWNq0~xDKDbkq!9KA+I_7< z3h(t{QV4rR(jNi*a)EPad-Qh@yARJH(EcjC591jITyjS3vRKl}h9Pp!LHhmYqmyIy z_#+B!nNU&GS#c7RllGKTwWkHQX4jnBWZkYKY}gIt8L>~$#s>6?b?mWMOhr-a*8v@| zHNvB|Tg%~nOkxipHi_7AJOM=y0yY$t?J}quN1W|^7*tm9X4@VCJmtjBHJ$k6jC1n5 z<XY?&#I6f9kJ=}I9o7skvCWV9oGAf*C1Jdact%j_DZGhu4De~ZiSq#9Sx84t zf5d4yTPI(Qw9y62p2M3@8IO7@YR}g$1vHO`+#5s6oWt+qwD)D@5i=_fq)ot5$?5OQ z_X@w)Xu)JvCr12iuf9|;CIy3ho5E8CJ&%W!Osg0y^(UMsRBS4Z92^TZJau3_v8c?( zR0J5>dBXk~V30Qk>sp6YYvGHmp28Ip@!#vjCVv*slVcXJTs%#*ZK0M#+Je1+_za$t zsP8Gf$-&crUxW87o)+NOjz{dLoty15&g&K;=Y9^UuRf0%U@C*szc(InUSIrqQ2K_m zeR_}c455W6bnVthE&Gl3S**6sE<`79R+oWieLC%&g#~xB4+GbE;|{Ey&i0+yi6{NY z8y`8#63)HJ*>E0wRk5Ry^^Zp*k=E@GG%M9gv*Nh487;nt0NAoiu{3UWA2N4vn(*_p0iNWb1@cY={R8qUVO52vQ&BDg%_SEBii-H47>2S zg9x06jk(meF!C($G{%+<#l7f5Wwb8*Bg|(n9+%~-DA26oD(mH+6}b?(5cT4&QytT3 zBuMc5)TW90w6n=|%GznxYtE+eO0%e)M%~>sQ>$!hl*-KsXS!6|=sNnOqc=IVlbfoQ z(M_hETMBnePzGov7Yr zBO}pP=AnY0I*eAOi^W=L+9?*jY_T|9S2I<@xnl9eOsQ(V=v+X2yBWHNX(%-{hKmp3V<2QJ+jT+O%=dCIGJqFh zvsjRb!X5x~k#mvrk@;9NN})gpK-)$mt$}82E;<=!3biIIqQQ8inV8Dz?ZzH5Hqac# zsJ;xvpq*(M57m>7mvS8lQd0}vUP?Jt#=K0iSVlj&=$5|SNT`fL+w9l6u7~2%PA^s; zo%F0`!%Jdl%~YF<+YBijchKZVP@@Z18pc&R+84EA0|=AR)<9SD1$B5Rp?iU-iLO^L zxPrkA4B9LeNCwxX_;4JLNI=?3$23!xNPx%((FzDc2}nO38H4&#v8OUnV2}WjgQQB~ zop>7Dx08^GjMsCxe$r8gW!w*!gR)SPbPzj?kGmN`GlH&(ELi8PIhZKXNHeC_&&5<^ zDy{Q#(fQb13}ZQ7OU_~J6yplgV>%?^CES^YqxFp_MB41dMjqbc#USK9zfJ$d>Q&{% zYR;((QGGRW+q@vBDtKI~qDZtq8VA4eSgpa12DBw@v7!!#Ii;Axd@{NKb!`Z=WN7J| z@JVMFw0lE3;!39B31qvwO6p$7TGxmoANh!IUjx7wZVMa)_ZBROIk*Ht7a?y8Z%nf? zF9nGaxxEUpKqliNyD48udx?{!>dX=i(j$UN%wiD^;E2n%P&l*ET(q^On^}G>P^Qu0 zq13X{DQ#!(d%gakDLd6_vDm?*jreM&19tE@9yf^~ZS`d!vrJnevy>_Rx$6-GGAk0x zDL2h2*Jv)7Gi_;2cs(+#jI?$!oc+r}`M9Kcv9O}YW7HyDf~i@(-pW9Rq6l3-qtvEa z8YZ$JVnCF~@feK^8Eg%9kh8q(1$6CYzB~fj6yw%Bbew4-=!)#aq_Zu;Gz`hauoeoa zD!OK?ps1rPY5>7Fr0TIOvrR_cWSxjZoP}8GYs`*T;TF9KU`J1}8D4gKwc<9*_36gW zrx2IcBrz+uZtQN2sz8Ja+pG0*sp{?o5ahxndl+G<9t?MsP zb1rpnAbu*joXQkc$>}rY^~vDb9W;5kEDiAsCL9W&LS(T3LR;RuR9ns^M1Ss@gT90w z-3~pPsKw{v^NG0xgf&rHYqY8V-Ntu(<(Ia8O&T%23zZr%9wH>#jQu~9Y){>G3M!Tg z#7;rY3Xo=w?oEBGQ4dCD9Vts~y4+>g#urUg>9OK40&3(B&&_nCrvf569Z#X;~EC zMMaIwetl2{G~Iw^$`V1NMC>9O=kZX`qR?-gnQ57snK_}%%$!s!RYqm8=u0Wt(85Mr zFP&v}My*i&cxTlmY5?yZr^n8zGz4?d8!R5JoIZ>hW2DraFxIN0Tc6A3@wYoajSu+- zzT}N9N;|dg!+9oMs-kljWTy+asDdE^e#m$Sk#7tF(#yQaQBl}0T+_E`8 zR;eiz$rW6+UIJLiA8h8`iTX@cWL%=|sSo#(w^WyA9Z|vXFJkEy2#;m#ir%SO{Z!4LHv>&&uRz=V zG+6;HmLjVAUuXG7ieS`Tu^gY#+8G2Qn8)@(>mM_c*j zNpGVsVJ}5j*vl1h7tNrXOC!A#AM`E+!Qx;y6WWSdW}6`+zz2I)8k@UC8jSE zpFn1D21TNlMP?;2kKi9O9p;l|sVQ`1@8TN;mm^UmgxZP|-Z}6Mt~sm)*#E6}ijt$o zJ|g~wd{fUj8}gMgaVpSPpaMC7I;KJw_m8imneRa-Uvq%fq`rpIpQr<_=h6Sr!Ei;E zp_Lm>IggbsU^h=q99HUURoI~h$+vRMDJm+kHI|*r0zq6 z?q@K9z{|2IzjN5}vXWDIDK{t`i=A4i*4~wxM2+lHo3~A+IRIx1CNATgBte=bo z*-_0DJ5xT2#Y1iU;QgLese9=#mK>{8;Z5^0aC7Qry zdM*6WTHP)K8mnE5$zY1<%wVtRD5>e3ZsJrMX%i}rF>Vk{P9k*W7%jO@XO2CLcjh31 z-N)p6j~yF1D!UCnFCZka!|mR^2M)Hs+5JaFfp(;%$|IHXRMqj44SCy;U}pwm{R+Ok z6t*=q$3&cfopbBuDW~Zdo;xZrQ!m{5My9-^FI%bRl#Ek5b<79){1mteO4a(fo!lqy zR*+us(+2`PXb8to%iaUn#}B?2I=&AEdEgu8kW<3W+)+O!+zxOGT{uB%(G}+S_2mq! z{2BwCLKjX?P-nAp+KwHooNfgv1*Qa%VzW7A#}IUUM#?2YZj5YNJxyqqV^d+I6@15d z3cm+gaGcFf9Gk+cT_)24Ix&c=bzPpQ*U?ut_`8?!y(ZoYuuyUbR*;Ik)6?~u&j-oN z_+n0UVTE~{QyqPhYfiO$%|=Y*p*U8@*iGUa-Y`H-YC%$io-Iy0u8YmF(fVoTJ8WWm z>Zh@r;Ny2-tPV z{d6$~ijC?F_6=uh#x%(JfJtV-PE8EetYm`r)w5n&;3lfe2sDF!^Li1wMG`>=j@Kj6 zn$v`T*N=dN(zFYDh-gYOnPAJngLBe(e!z4vYHg2$t~4X~|8_lY2FXv+OO`r;eBw*?sp*G5fHhgZ-@SHSCam z&R7XnnDoHC@I1l=Y_H^pBbe`r*p+Ck%Mo42`3M(9a@Lf_o&;{IJ1FbD&^fX&55AkL1tZ&x=JcvlDsY`W?zNY zduKVTSkBVq)l$&X^d6!IG~^gL8pL`yod%KYJ#DlVdrRdBrz4^7ftvVC1LOggBkXRo zu?IbfvkaEc{qklL3R#b z%2iljFuA4#uTmSU+gT(N0D5cnV&<8w&#zjcP?LH1>0HDg#GM*250H9Kl*_{Im}4 z#ge<}_WY3wK*^y3TQ(Y3#SS;yMgGdu=TJCJ?TFfx#~_cq@ZnLeRC{3^vOS z#$LSTgbR1Bxo52s<8qv6*h?6rB_Wd;7ke@ZdFep9bdx2ERh0>$wvojh-LD3{8Hu(o zHoFBI!xwX}(eZ>MJ;nnATExlr%dGGn41R^dI~fQ$taVwF;O+SEC6Yt4ly0iH@%W0@ zSMzHt*C{?rxJCDtaBBd7+5Y7*GM-}c9hU2M!4LORMOA^@KK+1z7?|0(&v$N2|Yv?dU!4it7QN9j+~*|hiwTu>yH>`J=Rfj zI${UUSK)-ZoUc06v1Nh7M5{YCE&Qzu@g24x#TwXX?LVv#;I$PZI9xW9~>%Yy`(<>aYEO_T}^h&lg^soA5 z(cgyST_}~uF9E?DNR2w9dAt$Hw3-27hXkfMtqGn69Fw60hTD!^ zErjTFpWNjZq8tU2@^Cm4>#foHOie8=e~=z}|C`7LJ+o^&>iQ7tLOlE<%=)Cm+2BQW zS^5$rda-hK3Aa|^fG{+ESfAO`xuT=C-$B-kw~RZQ+=&c@OTQN>`nMQ}7H+Fzl6_6P z;3X|c;JdVdy0OWt3+DD7IIoPIb^}<}~6EV`o5TB&t7&l7Ffy z^~aFYOUm&`SAPPL#r0)bpZUJKqsC9Yv>FpAb$a;(ynbu*Zs(n$^KF;_)95SSh|deX?}RPU9y)xS#eHL#JwybBYa+lu*gO0R(~_wn1`ZT@-+Ws zlrp0kowSiK=alqpp|$13vX~l{W_sC+Wm=DlHsmGi5RMpB^fI;X`OyVDVk&>^Vr6v6 z24_dg#$G&b76DBnUV@{AG2BYg_gLF_D{P{q@pWQ;jxL!jqoY%8ZtKsZm?f3G$TY0~ z1Q`}}CbwSuB1D88PBp`+gTEsp)~GeC$xn203_dvY zx;46_v(uxqO=mNkQ>fvFf@Z`Vd`3|%xHaaurMJtO1Aj_kTr&*W# zOh-juLnhmof`e4~A_cA79w6r7(T817ZRNOS7{t2zfF$wZxsPz>Y~macEGp}n4lAJm z1e~-sve6c|3+5P;7cc2?*Go>F;(HP4`isc>_BPEgfq(&@fDXadUq|VSYy2~$z4PCs z##~S%ht0Be{WtZ`a!K~CD^45l@e(bvq;ID^CH zNtm-wb{-w&eFr*rol%@)!fLRO=cU>ySg&74F5HR$7llR_v4f*SQx#kwnbc}L@ovtL z>2D*}MJ)}fklH-ATM$Gs#;6Sa>1*2E=0X*5k2S&QG}=2g7m14nsKV zdmG}d%lCsTxY%SaUSeOY)b;@thV_?FPwPr@E^ijY+&YuxuUp)Z$2pR+Tf~*6RX~Gx z1q&bS9ZmBjORz-7IaFd{v8?|FNJDWuX$rDaelbXpV!VXpUCg5dD=&V49HK7bCATbi zL_V48J^DLHZQY4=HE!JrJJ&ZG{`|Bd-yGe+lV3x3$tgAYobURa#nOYU)#PnUOEK&d z?1I&&*UKEWAy2qyW;|06j@-4=cxsH5m`^-jX6lg)9ra3F@^xg+w)Xy*b#@fGq>v># zEu6<_W@OiIr8GAFzjA3yQlxtRVkhD&ZCI-kNDKmRnJuBBCOKBao+(?V%l|Lt5F zRI~oH{{CEQKG95ZHHT93k6QDY`Q%&%KPj~uH#FiLc6cZGJ{vtjI3YukF0#JX)?-*| z;d;eJw>evN^1|Y9T_u;K!z1xqiSB})TZqXWB!yx8fU>=jK zTuX*iy>9w%{g4;UJ|E2wrM+0A-Y|+1>`_=r3v+}G`XA8Tlqq{%ZzowVgYKb3E|(h=Ha5h3P*;00)@H(E-R$wNi6%o07hM{Z)RZ3ef+|fV{&o zEDqk{7s$RtNQhW{WSEu9#o-<`>J`lFg8iG6V07G9yjgL6%l%5E^@~c*MRgh@KhUU@ z!7d%a1U_Qb@EB^Rj+lpSb58EOK)7N!368JNaKyy)9hkr}HW#?$*HjbgEBTq-4w#N8tdAPF38Cph4m#GE9WD`Y(>*a`WLO)}j ziJXDE$_&>t7`8<`!3sO39pG`Klo~D_(gYf~YX_gF7ahA0^U|;gE8{gs!4_{|91-x5 z+QTSF(regUbGcyvJ=t0<1-BioCa0F1VB!F|+t1(<1}hnekgXsj12hL{6-#A*N38z1 zW=dDP$t2d9!XuaL4q#?@IywgPh0IdcnJ5$x&i&K);-*q1avt{=hZ3#p_XgWs)GYqJ zBbr|MlH6pHi%5ks%I*4Nh5U0bMG$PtbymqMrKlj@x?1cwxEf2QsPKYgm{gW_NpVJ| z8J8a9V&x3xnKO{wg~0O}aPGtSC_6WHmPhc5q8at?BNcwHgv79;gL*qVi9Wzn#o~>i z-}mIVhJGZ0*btLk%Xk6Tg#9%bLZTTmVe_sJ>VhwDEs*RLSi|6VHsDe)x8hBMEd4o>{6t!;O z%l(7Aa&UElTOBe-inEwU(n}YW3)B_=J>s%C9PiSC36nQPhS3kR8B*1>g zT)ANmzh%dCO!IwWz$E6djSI8k7UY64pyXHU1dbUP;t-j{WtPblu6B!*4f7`k+-jYh zO0q8^1KBA}X$N~zLur#1mxI??GL)04OckQp#J9^LL~4*Bt|?u1rmidFFjg@SC!};c zV=6(?g=k0D$T;QLEwC#Fk(U!GHNP>ib5MM^4t}NVB`zHbT{^)?Nrxu5iUdo)_jcvq z5O%wj>)|z^?rulCy~x>&NHd}fxDAE7KT|1vIc`Ql3r@z&HX|T&%T?}yLqj4){ZQg& zirC$|JA^}iR0gItW=A)Vd+)x_q9~>mI)azs{VOpp+}gaa7}{G>*aMwuTdIV&{1!+mE`0un6#<&u>b2f#m!-(+xIQ=wL$5G&>OUyLKHr@ft4l`EBe=+)&+urcf z+pDGNQB~UcatO_LQEa5Ou^~U?vusn^(^Zg>?q?J6{q82xjy`6xv$TQ zW@9t>Wf*KKYic-|#`SSPUK*#NM2i^%hMQAFFX6CQ9g<0w`L|vX$ps(}`snM~kRfES z@+q@|`y zr`<}+u~Ub4KXmku|Q%HGPEW3Y+ARSdW| zFj{jDq0JuS)yItMl*-1mg2pQ zc-Mt^?PEtvQQrVj!EQ+;-L6C6&!WFU!k*u)pEiv{&NoZ`4XXG?eWX9f?Ao z?2`vui@~`I`x2tHQ%UTquB4FW?)(Ai+!55DV(@7OpF!Z|V0B>AnEU?d%RgfJXBm8s z!RHx#0Ri^cC$ycUVw%vhhMmFfs^n2zvcww~gv(QQ8bfF^hX!sh!Xg4;Xs>vcFX>-3u%drm|IT!*KgA2W{LlLDzUXSeT-=#|^VQTD zq%HpraH#OR|C3P*P6!j4F9sIs4em$d`*Jvllzt%@=dVHKKm~H(`fx7RpX@H}N5r0s zuS-VvJ z;^+%QVUS~OZ(o!-bBSD!^d-2(fA(h5hm$ez2R;S#cL2qc;19SYPcD{=txlldrKFBF z#E9kpLniuw-;U+TW0Qvx1sVh!u>2|)+GqmLH+g3AQDrXH!z5VHAESJmm=T?z+)Bp(>Nc2M%AkDy!TmK68 C`^;bf diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/appdirs.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/appdirs.py deleted file mode 100644 index ae67001a..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/appdirs.py +++ /dev/null @@ -1,608 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2005-2010 ActiveState Software Inc. -# Copyright (c) 2013 Eddy Petrișor - -"""Utilities for determining application-specific dirs. - -See for details and usage. -""" -# Dev Notes: -# - MSDN on where to store app data files: -# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 -# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html -# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - -__version_info__ = (1, 4, 3) -__version__ = '.'.join(map(str, __version_info__)) - - -import sys -import os - -PY3 = sys.version_info[0] == 3 - -if PY3: - unicode = str - -if sys.platform.startswith('java'): - import platform - os_name = platform.java_ver()[3][0] - if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. - system = 'win32' - elif os_name.startswith('Mac'): # "Mac OS X", etc. - system = 'darwin' - else: # "Linux", "SunOS", "FreeBSD", etc. - # Setting this to "linux2" is not ideal, but only Windows or Mac - # are actually checked for and the rest of the module expects - # *sys.platform* style strings. - system = 'linux2' -else: - system = sys.platform - - - -def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user data directories are: - Mac OS X: ~/Library/Application Support/ - Unix: ~/.local/share/ # or in $XDG_DATA_HOME, if defined - Win XP (not roaming): C:\Documents and Settings\\Application Data\\ - Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\ - Win 7 (not roaming): C:\Users\\AppData\Local\\ - Win 7 (roaming): C:\Users\\AppData\Roaming\\ - - For Unix, we follow the XDG spec and support $XDG_DATA_HOME. - That means, by default "~/.local/share/". - """ - if system == "win32": - if appauthor is None: - appauthor = appname - const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" - path = os.path.normpath(_get_win_folder(const)) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('~/Library/Application Support/') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of data dirs should be - returned. By default, the first item from XDG_DATA_DIRS is - returned, or '/usr/local/share/', - if XDG_DATA_DIRS is not set - - Typical site data directories are: - Mac OS X: /Library/Application Support/ - Unix: /usr/local/share/ or /usr/share/ - Win XP: C:\Documents and Settings\All Users\Application Data\\ - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - Win 7: C:\ProgramData\\ # Hidden, but writeable on Win 7. - - For Unix, this is using the $XDG_DATA_DIRS[0] default. - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - elif system == 'darwin': - path = os.path.expanduser('/Library/Application Support') - if appname: - path = os.path.join(path, appname) - else: - # XDG default for $XDG_DATA_DIRS - # only first, if multipath is False - path = os.getenv('XDG_DATA_DIRS', - os.pathsep.join(['/usr/local/share', '/usr/share'])) - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - if appname and version: - path = os.path.join(path, version) - return path - - -def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific config dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user config directories are: - Mac OS X: same as user_data_dir - Unix: ~/.config/ # or in $XDG_CONFIG_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. - That means, by default "~/.config/". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): - r"""Return full path to the user-shared data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "multipath" is an optional parameter only applicable to *nix - which indicates that the entire list of config dirs should be - returned. By default, the first item from XDG_CONFIG_DIRS is - returned, or '/etc/xdg/', if XDG_CONFIG_DIRS is not set - - Typical site config directories are: - Mac OS X: same as site_data_dir - Unix: /etc/xdg/ or $XDG_CONFIG_DIRS[i]/ for each value in - $XDG_CONFIG_DIRS - Win *: same as site_data_dir - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) - - For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False - - WARNING: Do not use this on Windows. See the Vista-Fail note above for why. - """ - if system in ["win32", "darwin"]: - path = site_data_dir(appname, appauthor) - if appname and version: - path = os.path.join(path, version) - else: - # XDG default for $XDG_CONFIG_DIRS - # only first, if multipath is False - path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] - if appname: - if version: - appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] - - if multipath: - path = os.pathsep.join(pathlist) - else: - path = pathlist[0] - return path - - -def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific cache dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Cache" to the base app data dir for Windows. See - discussion below. - - Typical user cache directories are: - Mac OS X: ~/Library/Caches/ - Unix: ~/.cache/ (XDG default) - Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Cache - Vista: C:\Users\\AppData\Local\\\Cache - - On Windows the only suggestion in the MSDN docs is that local settings go in - the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming - app data dir (the default returned by `user_data_dir` above). Apps typically - put cache data somewhere *under* the given dir here. Some examples: - ...\Mozilla\Firefox\Profiles\\Cache - ...\Acme\SuperApp\Cache\1.0 - OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. - This can be disabled with the `opinion=False` option. - """ - if system == "win32": - if appauthor is None: - appauthor = appname - path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) - if appname: - if appauthor is not False: - path = os.path.join(path, appauthor, appname) - else: - path = os.path.join(path, appname) - if opinion: - path = os.path.join(path, "Cache") - elif system == 'darwin': - path = os.path.expanduser('~/Library/Caches') - if appname: - path = os.path.join(path, appname) - else: - path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): - r"""Return full path to the user-specific state dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - - for a discussion of issues. - - Typical user state directories are: - Mac OS X: same as user_data_dir - Unix: ~/.local/state/ # or in $XDG_STATE_HOME, if defined - Win *: same as user_data_dir - - For Unix, we follow this Debian proposal - to extend the XDG spec and support $XDG_STATE_HOME. - - That means, by default "~/.local/state/". - """ - if system in ["win32", "darwin"]: - path = user_data_dir(appname, appauthor, None, roaming) - else: - path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) - if appname: - path = os.path.join(path, appname) - if appname and version: - path = os.path.join(path, version) - return path - - -def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): - r"""Return full path to the user-specific log dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "appauthor" (only used on Windows) is the name of the - appauthor or distributing body for this application. Typically - it is the owning company name. This falls back to appname. You may - pass False to disable it. - "version" is an optional version path element to append to the - path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this - would typically be ".". - Only applied when appname is present. - "opinion" (boolean) can be False to disable the appending of - "Logs" to the base app data dir for Windows, and "log" to the - base cache dir for Unix. See discussion below. - - Typical user log directories are: - Mac OS X: ~/Library/Logs/ - Unix: ~/.cache//log # or under $XDG_CACHE_HOME if defined - Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Logs - Vista: C:\Users\\AppData\Local\\\Logs - - On Windows the only suggestion in the MSDN docs is that local settings - go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in - examples of what some windows apps use for a logs dir.) - - OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` - value for Windows and appends "log" to the user cache dir for Unix. - This can be disabled with the `opinion=False` option. - """ - if system == "darwin": - path = os.path.join( - os.path.expanduser('~/Library/Logs'), - appname) - elif system == "win32": - path = user_data_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "Logs") - else: - path = user_cache_dir(appname, appauthor, version) - version = False - if opinion: - path = os.path.join(path, "log") - if appname and version: - path = os.path.join(path, version) - return path - - -class AppDirs(object): - """Convenience wrapper for getting application dirs.""" - def __init__(self, appname=None, appauthor=None, version=None, - roaming=False, multipath=False): - self.appname = appname - self.appauthor = appauthor - self.version = version - self.roaming = roaming - self.multipath = multipath - - @property - def user_data_dir(self): - return user_data_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_data_dir(self): - return site_data_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_config_dir(self): - return user_config_dir(self.appname, self.appauthor, - version=self.version, roaming=self.roaming) - - @property - def site_config_dir(self): - return site_config_dir(self.appname, self.appauthor, - version=self.version, multipath=self.multipath) - - @property - def user_cache_dir(self): - return user_cache_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_state_dir(self): - return user_state_dir(self.appname, self.appauthor, - version=self.version) - - @property - def user_log_dir(self): - return user_log_dir(self.appname, self.appauthor, - version=self.version) - - -#---- internal support stuff - -def _get_win_folder_from_registry(csidl_name): - """This is a fallback technique at best. I'm not sure if using the - registry for this guarantees us the correct answer for all CSIDL_* - names. - """ - if PY3: - import winreg as _winreg - else: - import _winreg - - shell_folder_name = { - "CSIDL_APPDATA": "AppData", - "CSIDL_COMMON_APPDATA": "Common AppData", - "CSIDL_LOCAL_APPDATA": "Local AppData", - }[csidl_name] - - key = _winreg.OpenKey( - _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - dir, type = _winreg.QueryValueEx(key, shell_folder_name) - return dir - - -def _get_win_folder_with_pywin32(csidl_name): - from win32com.shell import shellcon, shell - dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) - # Try to make this a unicode path because SHGetFolderPath does - # not return unicode strings when there is unicode data in the - # path. - try: - dir = unicode(dir) - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - try: - import win32api - dir = win32api.GetShortPathName(dir) - except ImportError: - pass - except UnicodeError: - pass - return dir - - -def _get_win_folder_with_ctypes(csidl_name): - import ctypes - - csidl_const = { - "CSIDL_APPDATA": 26, - "CSIDL_COMMON_APPDATA": 35, - "CSIDL_LOCAL_APPDATA": 28, - }[csidl_name] - - buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf2 = ctypes.create_unicode_buffer(1024) - if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): - buf = buf2 - - return buf.value - -def _get_win_folder_with_jna(csidl_name): - import array - from com.sun import jna - from com.sun.jna.platform import win32 - - buf_size = win32.WinDef.MAX_PATH * 2 - buf = array.zeros('c', buf_size) - shell = win32.Shell32.INSTANCE - shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - # Downgrade to short path name if have highbit chars. See - # . - has_high_char = False - for c in dir: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf = array.zeros('c', buf_size) - kernel = win32.Kernel32.INSTANCE - if kernel.GetShortPathName(dir, buf, buf_size): - dir = jna.Native.toString(buf.tostring()).rstrip("\0") - - return dir - -if system == "win32": - try: - import win32com.shell - _get_win_folder = _get_win_folder_with_pywin32 - except ImportError: - try: - from ctypes import windll - _get_win_folder = _get_win_folder_with_ctypes - except ImportError: - try: - import com.sun.jna - _get_win_folder = _get_win_folder_with_jna - except ImportError: - _get_win_folder = _get_win_folder_from_registry - - -#---- self test code - -if __name__ == "__main__": - appname = "MyApp" - appauthor = "MyCompany" - - props = ("user_data_dir", - "user_config_dir", - "user_cache_dir", - "user_state_dir", - "user_log_dir", - "site_data_dir", - "site_config_dir") - - print("-- app dirs %s --" % __version__) - - print("-- app dirs (with optional 'version')") - dirs = AppDirs(appname, appauthor, version="1.0") - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'version')") - dirs = AppDirs(appname, appauthor) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (without optional 'appauthor')") - dirs = AppDirs(appname) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) - - print("\n-- app dirs (with disabled 'appauthor')") - dirs = AppDirs(appname, appauthor=False) - for prop in props: - print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py deleted file mode 100644 index 95d330ef..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py +++ /dev/null @@ -1,21 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] - -__title__ = "packaging" -__summary__ = "Core utilities for Python packages" -__uri__ = "https://github.com/pypa/packaging" - -__version__ = "16.8" - -__author__ = "Donald Stufft and individual contributors" -__email__ = "donald@stufft.io" - -__license__ = "BSD or Apache License, Version 2.0" -__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py deleted file mode 100644 index 5ee62202..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -from .__about__ import ( - __author__, __copyright__, __email__, __license__, __summary__, __title__, - __uri__, __version__ -) - -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc deleted file mode 100644 index 3fca1650fc4db86d82faedddb41097a982817346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 753 zcmYk4&2G~`5XbGrX`HV%e5mIo5{F16+ZI$s2%$oIM5s~(2VYi>XJfBw?^^p2Dds_V z23~_F;G8QbUV#H*HlZpz^3OY~neonl{Ao1m2e=krzq22$Ao%H>|5uF86+Y$`0Re<% zP=!fYwUSoVPTFArEoego9XNt6#L&y*B!Yg@fkAQv!=wwNB!=Up2Pa7%#>oI4@!n~W z4B_!Im_GT1RfB1JcapA*DxKv_RJGD}7lYUcBb3}7*IG!+)=p;D`#r|2uq9_~H(<=T zs!H`1oi1Zei^J)LYoCiwpRv^0LTTJ%Ca+Ra9%4$7acO*+5o4LEw_4FDVt&?~Uf*{?F3!$h%@CL5x%oI9c^THuI*sjW9CM)C9udOpmX@fA?)al4kFJNG zyzY7UKSU2ahKO&09{at=?=Q4a6{m)0np-8g7lCPBD?^B`W|7845aa}Dk~C}vT9MWg7D-`9F0i>s&X8;57;01b z3Mq^Xy@6p8e9)uby!n9N`@Utg?tlJ(zz$Xv~1;izw(Yr~3*ZqP_@D3R6}9>?jYW0pTt|pP)>T#)3_Pir~xs zD%J83Lqsw|8YIIa!G<8!G8|l_vM#|XWJABToj8EDlmYIR^ICs2PR3b%N*(zdf}8w(nX~_!-VW{Oe^67OtN;K2 diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc deleted file mode 100644 index 6f9ec57d4b3e4fe83071dbc4d63b5bf18f12eef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1027 zcmah{&1w`u5bmGZ-O0My2nNNU!+H_+kR33W96}HjyahoN9E4^v-J5MQ(=&GWY}gP_ z2_$deRgZZMAEU3H@(P};nhkMtvY@J~s=L1W>ksSeeFC)e{g?R63Hgo2Dlsr#0lSYN zB$2crB~59`QdaVmQ}nSSN+T70=}7XJNPfi9?yVJp)l)tDM#WQ_u9>dt<0(6`drs1O zlD#M6-Zfy8F%KKrfvbwfE1}D}vOdI8&$ZK)3B%fIgxV_1( zE00>Jr9d6|0k9i@xTL4_lAQ80groacfEjpRxDc7FRH5%@+6ipH1uCyt=q&XJ;Vn+) z&mx&srAnO2t@4#o$)Wbbs=9JXV{}qyxu2;rGh0sCxw45e^Q6!RNxks1%4|<|5~sb| zf_F#Rp>j!mbO_)CWR*ZL(r{WA6iQ+p5KZEwv5M!rJYOpMu#I5L3H}R~ug8 zugmO0w0mx&#wL{ahyG8!o0>2^RbC zsF%<&!mJ+YTWzavx9z^ub}aImFq=7_2y=L81M-XA0BlG9Vcyz zk+#h&W`81WhdHbSBj7U^#xkog4@Q?&Sq;VtTVZt=J+{i$V63ur)_}3bHrOVNE9?r~ zax3-Th~r2^`ZTlvBx^Xw=LI|pox?29wp$XMN5*7qr6t9C$I^wR>3)3lyK$fUiieWx zSa81+X)5_3R(>KPe-MPa%lm=YQCtqW^tl-Nz39jvoa$~Y9_{Y=D$;xh^xg*@uKdCK z4s2I(B12fwAr~x`cnpXm(ebI$G6{78I=h3@)T0O{DXrp-(Q(8&+sJI&&7?C%I-qEb ztiwbTZG9jkYXruQt=8C1OWib)V2MBoiyD;T_B_~$G&C0i6>K=4@$J}d zy)uW7ZRvqRT8_bA@-m)FX-`wS4jLKS`jn9^+OYmo6m=|F@$t-=AlKq&}H0X{#W^lAY<%8K#VV3#Htex3Zf zfyC2_&;(d?y#NhmGiZ6yJDls#4g}_A0R+kxL&zIwfr(Oq(>id~J4G0123|XBIKNE$q<1siHW~T0=}&p$hZXvpwhH&&Wd%U1(T} z`|$inf|a-7{Q0i`#jR)6oy>a^3v&p^_^F9EHjHAOZC?)6Ur?Q?QHcze7iSZd2MZvV zrMdZ8Y+~-tkaR?uq(&K&kh1!m7`3kHWtXTTbJ) G3(rqxZuuqv diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc deleted file mode 100644 index d11aec502e7d5cd5e9e990c71bed3eea36b5817c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8965 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 diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc deleted file mode 100644 index 71b76d87ef8cd746f30176ea80cee696e620ee0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3924 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 diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc deleted file mode 100644 index d99fbfebf126b3c223d750fcbf2bda932404e83c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19833 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 Nr%mG^*LdN+{{o70>g50c diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 949e29484ddf7ce4c65a9e7a8009e488768bc8ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 466 zcmY*Vy-ve05VoDPjSA&Q@DdS9Bao075JF;N>4F#tLRK1^VCvYG9k)<1BA%li7^I0r(2Zx+xV%8|BTbB?vWrj)Nwv=X~ z#rIZJtQ!0qmdEk~c6LoG|#?4SYyWM}vL1Z(mi#!0NL!2hAkNv5w)f8hLUUc|l p9d2_-Q`f6xqZp^U8_J>Qcg;1}2-M`Xk;HO(78*_9?xQ5?M?V`PcSZmJ diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc deleted file mode 100644 index ee2958a0ec1bacddeae0da772c359761318a24ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10680 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".format(self.__class__.__name__, str(self)) - - def serialize(self): - raise NotImplementedError - - -class Variable(Node): - - def serialize(self): - return str(self) - - -class Value(Node): - - def serialize(self): - return '"{0}"'.format(self) - - -class Op(Node): - - def serialize(self): - return str(self) - - -VARIABLE = ( - L("implementation_version") | - L("platform_python_implementation") | - L("implementation_name") | - L("python_full_version") | - L("platform_release") | - L("platform_version") | - L("platform_machine") | - L("platform_system") | - L("python_version") | - L("sys_platform") | - L("os_name") | - L("os.name") | # PEP-345 - L("sys.platform") | # PEP-345 - L("platform.version") | # PEP-345 - L("platform.machine") | # PEP-345 - L("platform.python_implementation") | # PEP-345 - L("python_implementation") | # undocumented setuptools legacy - L("extra") -) -ALIASES = { - 'os.name': 'os_name', - 'sys.platform': 'sys_platform', - 'platform.version': 'platform_version', - 'platform.machine': 'platform_machine', - 'platform.python_implementation': 'platform_python_implementation', - 'python_implementation': 'platform_python_implementation' -} -VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) - -VERSION_CMP = ( - L("===") | - L("==") | - L(">=") | - L("<=") | - L("!=") | - L("~=") | - L(">") | - L("<") -) - -MARKER_OP = VERSION_CMP | L("not in") | L("in") -MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) - -MARKER_VALUE = QuotedString("'") | QuotedString('"') -MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) - -BOOLOP = L("and") | L("or") - -MARKER_VAR = VARIABLE | MARKER_VALUE - -MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) -MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) - -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() - -MARKER_EXPR = Forward() -MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) -MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) - -MARKER = stringStart + MARKER_EXPR + stringEnd - - -def _coerce_parse_result(results): - if isinstance(results, ParseResults): - return [_coerce_parse_result(i) for i in results] - else: - return results - - -def _format_marker(marker, first=True): - assert isinstance(marker, (list, tuple, string_types)) - - # Sometimes we have a structure like [[...]] which is a single item list - # where the single item is itself it's own list. In that case we want skip - # the rest of this function so that we don't get extraneous () on the - # outside. - if (isinstance(marker, list) and len(marker) == 1 and - isinstance(marker[0], (list, tuple))): - return _format_marker(marker[0]) - - if isinstance(marker, list): - inner = (_format_marker(m, first=False) for m in marker) - if first: - return " ".join(inner) - else: - return "(" + " ".join(inner) + ")" - elif isinstance(marker, tuple): - return " ".join([m.serialize() for m in marker]) - else: - return marker - - -_operators = { - "in": lambda lhs, rhs: lhs in rhs, - "not in": lambda lhs, rhs: lhs not in rhs, - "<": operator.lt, - "<=": operator.le, - "==": operator.eq, - "!=": operator.ne, - ">=": operator.ge, - ">": operator.gt, -} - - -def _eval_op(lhs, op, rhs): - try: - spec = Specifier("".join([op.serialize(), rhs])) - except InvalidSpecifier: - pass - else: - return spec.contains(lhs) - - oper = _operators.get(op.serialize()) - if oper is None: - raise UndefinedComparison( - "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) - ) - - return oper(lhs, rhs) - - -_undefined = object() - - -def _get_env(environment, name): - value = environment.get(name, _undefined) - - if value is _undefined: - raise UndefinedEnvironmentName( - "{0!r} does not exist in evaluation environment.".format(name) - ) - - return value - - -def _evaluate_markers(markers, environment): - groups = [[]] - - for marker in markers: - assert isinstance(marker, (list, tuple, string_types)) - - if isinstance(marker, list): - groups[-1].append(_evaluate_markers(marker, environment)) - elif isinstance(marker, tuple): - lhs, op, rhs = marker - - if isinstance(lhs, Variable): - lhs_value = _get_env(environment, lhs.value) - rhs_value = rhs.value - else: - lhs_value = lhs.value - rhs_value = _get_env(environment, rhs.value) - - groups[-1].append(_eval_op(lhs_value, op, rhs_value)) - else: - assert marker in ["and", "or"] - if marker == "or": - groups.append([]) - - return any(all(item) for item in groups) - - -def format_full_version(info): - version = '{0.major}.{0.minor}.{0.micro}'.format(info) - kind = info.releaselevel - if kind != 'final': - version += kind[0] + str(info.serial) - return version - - -def default_environment(): - if hasattr(sys, 'implementation'): - iver = format_full_version(sys.implementation.version) - implementation_name = sys.implementation.name - else: - iver = '0' - implementation_name = '' - - return { - "implementation_name": implementation_name, - "implementation_version": iver, - "os_name": os.name, - "platform_machine": platform.machine(), - "platform_release": platform.release(), - "platform_system": platform.system(), - "platform_version": platform.version(), - "python_full_version": platform.python_version(), - "platform_python_implementation": platform.python_implementation(), - "python_version": platform.python_version()[:3], - "sys_platform": sys.platform, - } - - -class Marker(object): - - def __init__(self, marker): - try: - self._markers = _coerce_parse_result(MARKER.parseString(marker)) - except ParseException as e: - err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( - marker, marker[e.loc:e.loc + 8]) - raise InvalidMarker(err_str) - - def __str__(self): - return _format_marker(self._markers) - - def __repr__(self): - return "".format(str(self)) - - def evaluate(self, environment=None): - """Evaluate a marker. - - Return the boolean from evaluating the given marker against the - environment. environment is an optional argument to override all or - part of the determined environment. - - The environment is determined from the current Python process. - """ - current_environment = default_environment() - if environment is not None: - current_environment.update(environment) - - return _evaluate_markers(self._markers, current_environment) diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py deleted file mode 100644 index 0c8c4a38..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py +++ /dev/null @@ -1,127 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import string -import re - -from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException -from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine -from pkg_resources.extern.pyparsing import Literal as L # noqa -from pkg_resources.extern.six.moves.urllib import parse as urlparse - -from .markers import MARKER_EXPR, Marker -from .specifiers import LegacySpecifier, Specifier, SpecifierSet - - -class InvalidRequirement(ValueError): - """ - An invalid requirement was found, users should refer to PEP 508. - """ - - -ALPHANUM = Word(string.ascii_letters + string.digits) - -LBRACKET = L("[").suppress() -RBRACKET = L("]").suppress() -LPAREN = L("(").suppress() -RPAREN = L(")").suppress() -COMMA = L(",").suppress() -SEMICOLON = L(";").suppress() -AT = L("@").suppress() - -PUNCTUATION = Word("-_.") -IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) -IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) - -NAME = IDENTIFIER("name") -EXTRA = IDENTIFIER - -URI = Regex(r'[^ ]+')("url") -URL = (AT + URI) - -EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) -EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") - -VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) -VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) - -VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY -VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), - joinString=",", adjacent=False)("_raw_spec") -_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) -_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') - -VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") -VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) - -MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") -MARKER_EXPR.setParseAction( - lambda s, l, t: Marker(s[t._original_start:t._original_end]) -) -MARKER_SEPERATOR = SEMICOLON -MARKER = MARKER_SEPERATOR + MARKER_EXPR - -VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) -URL_AND_MARKER = URL + Optional(MARKER) - -NAMED_REQUIREMENT = \ - NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) - -REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd - - -class Requirement(object): - """Parse a requirement. - - Parse a given requirement string into its parts, such as name, specifier, - URL, and extras. Raises InvalidRequirement on a badly-formed requirement - string. - """ - - # TODO: Can we test whether something is contained within a requirement? - # If so how do we do that? Do we need to test against the _name_ of - # the thing as well as the version? What about the markers? - # TODO: Can we normalize the name and extra name? - - def __init__(self, requirement_string): - try: - req = REQUIREMENT.parseString(requirement_string) - except ParseException as e: - raise InvalidRequirement( - "Invalid requirement, parse error at \"{0!r}\"".format( - requirement_string[e.loc:e.loc + 8])) - - self.name = req.name - if req.url: - parsed_url = urlparse.urlparse(req.url) - if not (parsed_url.scheme and parsed_url.netloc) or ( - not parsed_url.scheme and not parsed_url.netloc): - raise InvalidRequirement("Invalid URL given") - self.url = req.url - else: - self.url = None - self.extras = set(req.extras.asList() if req.extras else []) - self.specifier = SpecifierSet(req.specifier) - self.marker = req.marker if req.marker else None - - def __str__(self): - parts = [self.name] - - if self.extras: - parts.append("[{0}]".format(",".join(sorted(self.extras)))) - - if self.specifier: - parts.append(str(self.specifier)) - - if self.url: - parts.append("@ {0}".format(self.url)) - - if self.marker: - parts.append("; {0}".format(self.marker)) - - return "".join(parts) - - def __repr__(self): - return "".format(str(self)) diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py deleted file mode 100644 index 7f5a76cf..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py +++ /dev/null @@ -1,774 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import abc -import functools -import itertools -import re - -from ._compat import string_types, with_metaclass -from .version import Version, LegacyVersion, parse - - -class InvalidSpecifier(ValueError): - """ - An invalid specifier was found, users should refer to PEP 440. - """ - - -class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): - - @abc.abstractmethod - def __str__(self): - """ - Returns the str representation of this Specifier like object. This - should be representative of the Specifier itself. - """ - - @abc.abstractmethod - def __hash__(self): - """ - Returns a hash value for this Specifier like object. - """ - - @abc.abstractmethod - def __eq__(self, other): - """ - Returns a boolean representing whether or not the two Specifier like - objects are equal. - """ - - @abc.abstractmethod - def __ne__(self, other): - """ - Returns a boolean representing whether or not the two Specifier like - objects are not equal. - """ - - @abc.abstractproperty - def prereleases(self): - """ - Returns whether or not pre-releases as a whole are allowed by this - specifier. - """ - - @prereleases.setter - def prereleases(self, value): - """ - Sets whether or not pre-releases as a whole are allowed by this - specifier. - """ - - @abc.abstractmethod - def contains(self, item, prereleases=None): - """ - Determines if the given item is contained within this specifier. - """ - - @abc.abstractmethod - def filter(self, iterable, prereleases=None): - """ - Takes an iterable of items and filters them so that only items which - are contained within this specifier are allowed in it. - """ - - -class _IndividualSpecifier(BaseSpecifier): - - _operators = {} - - def __init__(self, spec="", prereleases=None): - match = self._regex.search(spec) - if not match: - raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) - - self._spec = ( - match.group("operator").strip(), - match.group("version").strip(), - ) - - # Store whether or not this Specifier should accept prereleases - self._prereleases = prereleases - - def __repr__(self): - pre = ( - ", prereleases={0!r}".format(self.prereleases) - if self._prereleases is not None - else "" - ) - - return "<{0}({1!r}{2})>".format( - self.__class__.__name__, - str(self), - pre, - ) - - def __str__(self): - return "{0}{1}".format(*self._spec) - - def __hash__(self): - return hash(self._spec) - - def __eq__(self, other): - if isinstance(other, string_types): - try: - other = self.__class__(other) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._spec == other._spec - - def __ne__(self, other): - if isinstance(other, string_types): - try: - other = self.__class__(other) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._spec != other._spec - - def _get_operator(self, op): - return getattr(self, "_compare_{0}".format(self._operators[op])) - - def _coerce_version(self, version): - if not isinstance(version, (LegacyVersion, Version)): - version = parse(version) - return version - - @property - def operator(self): - return self._spec[0] - - @property - def version(self): - return self._spec[1] - - @property - def prereleases(self): - return self._prereleases - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - def __contains__(self, item): - return self.contains(item) - - def contains(self, item, prereleases=None): - # Determine if prereleases are to be allowed or not. - if prereleases is None: - prereleases = self.prereleases - - # Normalize item to a Version or LegacyVersion, this allows us to have - # a shortcut for ``"2.0" in Specifier(">=2") - item = self._coerce_version(item) - - # Determine if we should be supporting prereleases in this specifier - # or not, if we do not support prereleases than we can short circuit - # logic if this version is a prereleases. - if item.is_prerelease and not prereleases: - return False - - # Actually do the comparison to determine if this item is contained - # within this Specifier or not. - return self._get_operator(self.operator)(item, self.version) - - def filter(self, iterable, prereleases=None): - yielded = False - found_prereleases = [] - - kw = {"prereleases": prereleases if prereleases is not None else True} - - # Attempt to iterate over all the values in the iterable and if any of - # them match, yield them. - for version in iterable: - parsed_version = self._coerce_version(version) - - if self.contains(parsed_version, **kw): - # If our version is a prerelease, and we were not set to allow - # prereleases, then we'll store it for later incase nothing - # else matches this specifier. - if (parsed_version.is_prerelease and not - (prereleases or self.prereleases)): - found_prereleases.append(version) - # Either this is not a prerelease, or we should have been - # accepting prereleases from the begining. - else: - yielded = True - yield version - - # Now that we've iterated over everything, determine if we've yielded - # any values, and if we have not and we have any prereleases stored up - # then we will go ahead and yield the prereleases. - if not yielded and found_prereleases: - for version in found_prereleases: - yield version - - -class LegacySpecifier(_IndividualSpecifier): - - _regex_str = ( - r""" - (?P(==|!=|<=|>=|<|>)) - \s* - (?P - [^,;\s)]* # Since this is a "legacy" specifier, and the version - # string can be just about anything, we match everything - # except for whitespace, a semi-colon for marker support, - # a closing paren since versions can be enclosed in - # them, and a comma since it's a version separator. - ) - """ - ) - - _regex = re.compile( - r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) - - _operators = { - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - } - - def _coerce_version(self, version): - if not isinstance(version, LegacyVersion): - version = LegacyVersion(str(version)) - return version - - def _compare_equal(self, prospective, spec): - return prospective == self._coerce_version(spec) - - def _compare_not_equal(self, prospective, spec): - return prospective != self._coerce_version(spec) - - def _compare_less_than_equal(self, prospective, spec): - return prospective <= self._coerce_version(spec) - - def _compare_greater_than_equal(self, prospective, spec): - return prospective >= self._coerce_version(spec) - - def _compare_less_than(self, prospective, spec): - return prospective < self._coerce_version(spec) - - def _compare_greater_than(self, prospective, spec): - return prospective > self._coerce_version(spec) - - -def _require_version_compare(fn): - @functools.wraps(fn) - def wrapped(self, prospective, spec): - if not isinstance(prospective, Version): - return False - return fn(self, prospective, spec) - return wrapped - - -class Specifier(_IndividualSpecifier): - - _regex_str = ( - r""" - (?P(~=|==|!=|<=|>=|<|>|===)) - (?P - (?: - # The identity operators allow for an escape hatch that will - # do an exact string match of the version you wish to install. - # This will not be parsed by PEP 440 and we cannot determine - # any semantic meaning from it. This operator is discouraged - # but included entirely as an escape hatch. - (?<====) # Only match for the identity operator - \s* - [^\s]* # We just match everything, except for whitespace - # since we are only testing for strict identity. - ) - | - (?: - # The (non)equality operators allow for wild card and local - # versions to be specified so we have to define these two - # operators separately to enable that. - (?<===|!=) # Only match for equals and not equals - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - - # You cannot use a wild card and a dev or local version - # together so group them with a | and make them optional. - (?: - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local - | - \.\* # Wild card syntax of .* - )? - ) - | - (?: - # The compatible operator requires at least two digits in the - # release segment. - (?<=~=) # Only match for the compatible operator - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) - (?: # pre release - [-_\.]? - (a|b|c|rc|alpha|beta|pre|preview) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - | - (?: - # All other operators only allow a sub set of what the - # (non)equality operators do. Specifically they do not allow - # local versions to be specified nor do they allow the prefix - # matching wild cards. - (?=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - "===": "arbitrary", - } - - @_require_version_compare - def _compare_compatible(self, prospective, spec): - # Compatible releases have an equivalent combination of >= and ==. That - # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to - # implement this in terms of the other specifiers instead of - # implementing it ourselves. The only thing we need to do is construct - # the other specifiers. - - # We want everything but the last item in the version, but we want to - # ignore post and dev releases and we want to treat the pre-release as - # it's own separate segment. - prefix = ".".join( - list( - itertools.takewhile( - lambda x: (not x.startswith("post") and not - x.startswith("dev")), - _version_split(spec), - ) - )[:-1] - ) - - # Add the prefix notation to the end of our string - prefix += ".*" - - return (self._get_operator(">=")(prospective, spec) and - self._get_operator("==")(prospective, prefix)) - - @_require_version_compare - def _compare_equal(self, prospective, spec): - # We need special logic to handle prefix matching - if spec.endswith(".*"): - # In the case of prefix matching we want to ignore local segment. - prospective = Version(prospective.public) - # Split the spec out by dots, and pretend that there is an implicit - # dot in between a release segment and a pre-release segment. - spec = _version_split(spec[:-2]) # Remove the trailing .* - - # Split the prospective version out by dots, and pretend that there - # is an implicit dot in between a release segment and a pre-release - # segment. - prospective = _version_split(str(prospective)) - - # Shorten the prospective version to be the same length as the spec - # so that we can determine if the specifier is a prefix of the - # prospective version or not. - prospective = prospective[:len(spec)] - - # Pad out our two sides with zeros so that they both equal the same - # length. - spec, prospective = _pad_version(spec, prospective) - else: - # Convert our spec string into a Version - spec = Version(spec) - - # If the specifier does not have a local segment, then we want to - # act as if the prospective version also does not have a local - # segment. - if not spec.local: - prospective = Version(prospective.public) - - return prospective == spec - - @_require_version_compare - def _compare_not_equal(self, prospective, spec): - return not self._compare_equal(prospective, spec) - - @_require_version_compare - def _compare_less_than_equal(self, prospective, spec): - return prospective <= Version(spec) - - @_require_version_compare - def _compare_greater_than_equal(self, prospective, spec): - return prospective >= Version(spec) - - @_require_version_compare - def _compare_less_than(self, prospective, spec): - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = Version(spec) - - # Check to see if the prospective version is less than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective < spec: - return False - - # This special case is here so that, unless the specifier itself - # includes is a pre-release version, that we do not accept pre-release - # versions for the version mentioned in the specifier (e.g. <3.1 should - # not match 3.1.dev0, but should match 3.0.dev0). - if not spec.is_prerelease and prospective.is_prerelease: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # If we've gotten to here, it means that prospective version is both - # less than the spec version *and* it's not a pre-release of the same - # version in the spec. - return True - - @_require_version_compare - def _compare_greater_than(self, prospective, spec): - # Convert our spec to a Version instance, since we'll want to work with - # it as a version. - spec = Version(spec) - - # Check to see if the prospective version is greater than the spec - # version. If it's not we can short circuit and just return False now - # instead of doing extra unneeded work. - if not prospective > spec: - return False - - # This special case is here so that, unless the specifier itself - # includes is a post-release version, that we do not accept - # post-release versions for the version mentioned in the specifier - # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). - if not spec.is_postrelease and prospective.is_postrelease: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # Ensure that we do not allow a local version of the version mentioned - # in the specifier, which is techincally greater than, to match. - if prospective.local is not None: - if Version(prospective.base_version) == Version(spec.base_version): - return False - - # If we've gotten to here, it means that prospective version is both - # greater than the spec version *and* it's not a pre-release of the - # same version in the spec. - return True - - def _compare_arbitrary(self, prospective, spec): - return str(prospective).lower() == str(spec).lower() - - @property - def prereleases(self): - # If there is an explicit prereleases set for this, then we'll just - # blindly use that. - if self._prereleases is not None: - return self._prereleases - - # Look at all of our specifiers and determine if they are inclusive - # operators, and if they are if they are including an explicit - # prerelease. - operator, version = self._spec - if operator in ["==", ">=", "<=", "~=", "==="]: - # The == specifier can include a trailing .*, if it does we - # want to remove before parsing. - if operator == "==" and version.endswith(".*"): - version = version[:-2] - - # Parse the version, and if it is a pre-release than this - # specifier allows pre-releases. - if parse(version).is_prerelease: - return True - - return False - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - -_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") - - -def _version_split(version): - result = [] - for item in version.split("."): - match = _prefix_regex.search(item) - if match: - result.extend(match.groups()) - else: - result.append(item) - return result - - -def _pad_version(left, right): - left_split, right_split = [], [] - - # Get the release segment of our versions - left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) - right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) - - # Get the rest of our versions - left_split.append(left[len(left_split[0]):]) - right_split.append(right[len(right_split[0]):]) - - # Insert our padding - left_split.insert( - 1, - ["0"] * max(0, len(right_split[0]) - len(left_split[0])), - ) - right_split.insert( - 1, - ["0"] * max(0, len(left_split[0]) - len(right_split[0])), - ) - - return ( - list(itertools.chain(*left_split)), - list(itertools.chain(*right_split)), - ) - - -class SpecifierSet(BaseSpecifier): - - def __init__(self, specifiers="", prereleases=None): - # Split on , to break each indidivual specifier into it's own item, and - # strip each item to remove leading/trailing whitespace. - specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] - - # Parsed each individual specifier, attempting first to make it a - # Specifier and falling back to a LegacySpecifier. - parsed = set() - for specifier in specifiers: - try: - parsed.add(Specifier(specifier)) - except InvalidSpecifier: - parsed.add(LegacySpecifier(specifier)) - - # Turn our parsed specifiers into a frozen set and save them for later. - self._specs = frozenset(parsed) - - # Store our prereleases value so we can use it later to determine if - # we accept prereleases or not. - self._prereleases = prereleases - - def __repr__(self): - pre = ( - ", prereleases={0!r}".format(self.prereleases) - if self._prereleases is not None - else "" - ) - - return "".format(str(self), pre) - - def __str__(self): - return ",".join(sorted(str(s) for s in self._specs)) - - def __hash__(self): - return hash(self._specs) - - def __and__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - specifier = SpecifierSet() - specifier._specs = frozenset(self._specs | other._specs) - - if self._prereleases is None and other._prereleases is not None: - specifier._prereleases = other._prereleases - elif self._prereleases is not None and other._prereleases is None: - specifier._prereleases = self._prereleases - elif self._prereleases == other._prereleases: - specifier._prereleases = self._prereleases - else: - raise ValueError( - "Cannot combine SpecifierSets with True and False prerelease " - "overrides." - ) - - return specifier - - def __eq__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._specs == other._specs - - def __ne__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._specs != other._specs - - def __len__(self): - return len(self._specs) - - def __iter__(self): - return iter(self._specs) - - @property - def prereleases(self): - # If we have been given an explicit prerelease modifier, then we'll - # pass that through here. - if self._prereleases is not None: - return self._prereleases - - # If we don't have any specifiers, and we don't have a forced value, - # then we'll just return None since we don't know if this should have - # pre-releases or not. - if not self._specs: - return None - - # Otherwise we'll see if any of the given specifiers accept - # prereleases, if any of them do we'll return True, otherwise False. - return any(s.prereleases for s in self._specs) - - @prereleases.setter - def prereleases(self, value): - self._prereleases = value - - def __contains__(self, item): - return self.contains(item) - - def contains(self, item, prereleases=None): - # Ensure that our item is a Version or LegacyVersion instance. - if not isinstance(item, (LegacyVersion, Version)): - item = parse(item) - - # Determine if we're forcing a prerelease or not, if we're not forcing - # one for this particular filter call, then we'll use whatever the - # SpecifierSet thinks for whether or not we should support prereleases. - if prereleases is None: - prereleases = self.prereleases - - # We can determine if we're going to allow pre-releases by looking to - # see if any of the underlying items supports them. If none of them do - # and this item is a pre-release then we do not allow it and we can - # short circuit that here. - # Note: This means that 1.0.dev1 would not be contained in something - # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 - if not prereleases and item.is_prerelease: - return False - - # We simply dispatch to the underlying specs here to make sure that the - # given version is contained within all of them. - # Note: This use of all() here means that an empty set of specifiers - # will always return True, this is an explicit design decision. - return all( - s.contains(item, prereleases=prereleases) - for s in self._specs - ) - - def filter(self, iterable, prereleases=None): - # Determine if we're forcing a prerelease or not, if we're not forcing - # one for this particular filter call, then we'll use whatever the - # SpecifierSet thinks for whether or not we should support prereleases. - if prereleases is None: - prereleases = self.prereleases - - # If we have any specifiers, then we want to wrap our iterable in the - # filter method for each one, this will act as a logical AND amongst - # each specifier. - if self._specs: - for spec in self._specs: - iterable = spec.filter(iterable, prereleases=bool(prereleases)) - return iterable - # If we do not have any specifiers, then we need to have a rough filter - # which will filter out any pre-releases, unless there are no final - # releases, and which will filter out LegacyVersion in general. - else: - filtered = [] - found_prereleases = [] - - for item in iterable: - # Ensure that we some kind of Version class for this item. - if not isinstance(item, (LegacyVersion, Version)): - parsed_version = parse(item) - else: - parsed_version = item - - # Filter out any item which is parsed as a LegacyVersion - if isinstance(parsed_version, LegacyVersion): - continue - - # Store any item which is a pre-release for later unless we've - # already found a final version or we are accepting prereleases - if parsed_version.is_prerelease and not prereleases: - if not filtered: - found_prereleases.append(item) - else: - filtered.append(item) - - # If we've found no items except for pre-releases, then we'll go - # ahead and use the pre-releases - if not filtered and found_prereleases and prereleases is None: - return found_prereleases - - return filtered diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py deleted file mode 100644 index 942387ce..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import re - - -_canonicalize_regex = re.compile(r"[-_.]+") - - -def canonicalize_name(name): - # This is taken from PEP 503. - return _canonicalize_regex.sub("-", name).lower() diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py deleted file mode 100644 index 83b5ee8c..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py +++ /dev/null @@ -1,393 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import absolute_import, division, print_function - -import collections -import itertools -import re - -from ._structures import Infinity - - -__all__ = [ - "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" -] - - -_Version = collections.namedtuple( - "_Version", - ["epoch", "release", "dev", "pre", "post", "local"], -) - - -def parse(version): - """ - Parse the given version string and return either a :class:`Version` object - or a :class:`LegacyVersion` object depending on if the given version is - a valid PEP 440 version or a legacy version. - """ - try: - return Version(version) - except InvalidVersion: - return LegacyVersion(version) - - -class InvalidVersion(ValueError): - """ - An invalid version was found, users should refer to PEP 440. - """ - - -class _BaseVersion(object): - - def __hash__(self): - return hash(self._key) - - def __lt__(self, other): - return self._compare(other, lambda s, o: s < o) - - def __le__(self, other): - return self._compare(other, lambda s, o: s <= o) - - def __eq__(self, other): - return self._compare(other, lambda s, o: s == o) - - def __ge__(self, other): - return self._compare(other, lambda s, o: s >= o) - - def __gt__(self, other): - return self._compare(other, lambda s, o: s > o) - - def __ne__(self, other): - return self._compare(other, lambda s, o: s != o) - - def _compare(self, other, method): - if not isinstance(other, _BaseVersion): - return NotImplemented - - return method(self._key, other._key) - - -class LegacyVersion(_BaseVersion): - - def __init__(self, version): - self._version = str(version) - self._key = _legacy_cmpkey(self._version) - - def __str__(self): - return self._version - - def __repr__(self): - return "".format(repr(str(self))) - - @property - def public(self): - return self._version - - @property - def base_version(self): - return self._version - - @property - def local(self): - return None - - @property - def is_prerelease(self): - return False - - @property - def is_postrelease(self): - return False - - -_legacy_version_component_re = re.compile( - r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, -) - -_legacy_version_replacement_map = { - "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", -} - - -def _parse_version_parts(s): - for part in _legacy_version_component_re.split(s): - part = _legacy_version_replacement_map.get(part, part) - - if not part or part == ".": - continue - - if part[:1] in "0123456789": - # pad for numeric comparison - yield part.zfill(8) - else: - yield "*" + part - - # ensure that alpha/beta/candidate are before final - yield "*final" - - -def _legacy_cmpkey(version): - # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch - # greater than or equal to 0. This will effectively put the LegacyVersion, - # which uses the defacto standard originally implemented by setuptools, - # as before all PEP 440 versions. - epoch = -1 - - # This scheme is taken from pkg_resources.parse_version setuptools prior to - # it's adoption of the packaging library. - parts = [] - for part in _parse_version_parts(version.lower()): - if part.startswith("*"): - # remove "-" before a prerelease tag - if part < "*final": - while parts and parts[-1] == "*final-": - parts.pop() - - # remove trailing zeros from each series of numeric parts - while parts and parts[-1] == "00000000": - parts.pop() - - parts.append(part) - parts = tuple(parts) - - return epoch, parts - -# Deliberately not anchored to the start and end of the string, to make it -# easier for 3rd party code to reuse -VERSION_PATTERN = r""" - v? - (?: - (?:(?P[0-9]+)!)? # epoch - (?P[0-9]+(?:\.[0-9]+)*) # release segment - (?P

                                              # pre-release
    -            [-_\.]?
    -            (?P(a|b|c|rc|alpha|beta|pre|preview))
    -            [-_\.]?
    -            (?P[0-9]+)?
    -        )?
    -        (?P                                         # post release
    -            (?:-(?P[0-9]+))
    -            |
    -            (?:
    -                [-_\.]?
    -                (?Ppost|rev|r)
    -                [-_\.]?
    -                (?P[0-9]+)?
    -            )
    -        )?
    -        (?P                                          # dev release
    -            [-_\.]?
    -            (?Pdev)
    -            [-_\.]?
    -            (?P[0-9]+)?
    -        )?
    -    )
    -    (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
    -"""
    -
    -
    -class Version(_BaseVersion):
    -
    -    _regex = re.compile(
    -        r"^\s*" + VERSION_PATTERN + r"\s*$",
    -        re.VERBOSE | re.IGNORECASE,
    -    )
    -
    -    def __init__(self, version):
    -        # Validate the version and parse it into pieces
    -        match = self._regex.search(version)
    -        if not match:
    -            raise InvalidVersion("Invalid version: '{0}'".format(version))
    -
    -        # Store the parsed out pieces of the version
    -        self._version = _Version(
    -            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
    -            release=tuple(int(i) for i in match.group("release").split(".")),
    -            pre=_parse_letter_version(
    -                match.group("pre_l"),
    -                match.group("pre_n"),
    -            ),
    -            post=_parse_letter_version(
    -                match.group("post_l"),
    -                match.group("post_n1") or match.group("post_n2"),
    -            ),
    -            dev=_parse_letter_version(
    -                match.group("dev_l"),
    -                match.group("dev_n"),
    -            ),
    -            local=_parse_local_version(match.group("local")),
    -        )
    -
    -        # Generate a key which will be used for sorting
    -        self._key = _cmpkey(
    -            self._version.epoch,
    -            self._version.release,
    -            self._version.pre,
    -            self._version.post,
    -            self._version.dev,
    -            self._version.local,
    -        )
    -
    -    def __repr__(self):
    -        return "".format(repr(str(self)))
    -
    -    def __str__(self):
    -        parts = []
    -
    -        # Epoch
    -        if self._version.epoch != 0:
    -            parts.append("{0}!".format(self._version.epoch))
    -
    -        # Release segment
    -        parts.append(".".join(str(x) for x in self._version.release))
    -
    -        # Pre-release
    -        if self._version.pre is not None:
    -            parts.append("".join(str(x) for x in self._version.pre))
    -
    -        # Post-release
    -        if self._version.post is not None:
    -            parts.append(".post{0}".format(self._version.post[1]))
    -
    -        # Development release
    -        if self._version.dev is not None:
    -            parts.append(".dev{0}".format(self._version.dev[1]))
    -
    -        # Local version segment
    -        if self._version.local is not None:
    -            parts.append(
    -                "+{0}".format(".".join(str(x) for x in self._version.local))
    -            )
    -
    -        return "".join(parts)
    -
    -    @property
    -    def public(self):
    -        return str(self).split("+", 1)[0]
    -
    -    @property
    -    def base_version(self):
    -        parts = []
    -
    -        # Epoch
    -        if self._version.epoch != 0:
    -            parts.append("{0}!".format(self._version.epoch))
    -
    -        # Release segment
    -        parts.append(".".join(str(x) for x in self._version.release))
    -
    -        return "".join(parts)
    -
    -    @property
    -    def local(self):
    -        version_string = str(self)
    -        if "+" in version_string:
    -            return version_string.split("+", 1)[1]
    -
    -    @property
    -    def is_prerelease(self):
    -        return bool(self._version.dev or self._version.pre)
    -
    -    @property
    -    def is_postrelease(self):
    -        return bool(self._version.post)
    -
    -
    -def _parse_letter_version(letter, number):
    -    if letter:
    -        # We consider there to be an implicit 0 in a pre-release if there is
    -        # not a numeral associated with it.
    -        if number is None:
    -            number = 0
    -
    -        # We normalize any letters to their lower case form
    -        letter = letter.lower()
    -
    -        # We consider some words to be alternate spellings of other words and
    -        # in those cases we want to normalize the spellings to our preferred
    -        # spelling.
    -        if letter == "alpha":
    -            letter = "a"
    -        elif letter == "beta":
    -            letter = "b"
    -        elif letter in ["c", "pre", "preview"]:
    -            letter = "rc"
    -        elif letter in ["rev", "r"]:
    -            letter = "post"
    -
    -        return letter, int(number)
    -    if not letter and number:
    -        # We assume if we are given a number, but we are not given a letter
    -        # then this is using the implicit post release syntax (e.g. 1.0-1)
    -        letter = "post"
    -
    -        return letter, int(number)
    -
    -
    -_local_version_seperators = re.compile(r"[\._-]")
    -
    -
    -def _parse_local_version(local):
    -    """
    -    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
    -    """
    -    if local is not None:
    -        return tuple(
    -            part.lower() if not part.isdigit() else int(part)
    -            for part in _local_version_seperators.split(local)
    -        )
    -
    -
    -def _cmpkey(epoch, release, pre, post, dev, local):
    -    # When we compare a release version, we want to compare it with all of the
    -    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    -    # leading zeros until we come to something non zero, then take the rest
    -    # re-reverse it back into the correct order and make it a tuple and use
    -    # that for our sorting key.
    -    release = tuple(
    -        reversed(list(
    -            itertools.dropwhile(
    -                lambda x: x == 0,
    -                reversed(release),
    -            )
    -        ))
    -    )
    -
    -    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    -    # We'll do this by abusing the pre segment, but we _only_ want to do this
    -    # if there is not a pre or a post segment. If we have one of those then
    -    # the normal sorting rules will handle this case correctly.
    -    if pre is None and post is None and dev is not None:
    -        pre = -Infinity
    -    # Versions without a pre-release (except as noted above) should sort after
    -    # those with one.
    -    elif pre is None:
    -        pre = Infinity
    -
    -    # Versions without a post segment should sort before those with one.
    -    if post is None:
    -        post = -Infinity
    -
    -    # Versions without a development segment should sort after those with one.
    -    if dev is None:
    -        dev = Infinity
    -
    -    if local is None:
    -        # Versions without a local segment should sort before those with one.
    -        local = -Infinity
    -    else:
    -        # Versions with a local segment need that segment parsed to implement
    -        # the sorting rules in PEP440.
    -        # - Alpha numeric segments sort before numeric segments
    -        # - Alpha numeric segments sort lexicographically
    -        # - Numeric segments sort numerically
    -        # - Shorter versions sort before longer versions when the prefixes
    -        #   match exactly
    -        local = tuple(
    -            (i, "") if isinstance(i, int) else (-Infinity, i)
    -            for i in local
    -        )
    -
    -    return epoch, release, pre, post, dev, local
    diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/pyparsing.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/pyparsing.py
    deleted file mode 100644
    index cf75e1e5..00000000
    --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/pyparsing.py
    +++ /dev/null
    @@ -1,5742 +0,0 @@
    -# module pyparsing.py
    -#
    -# Copyright (c) 2003-2018  Paul T. McGuire
    -#
    -# Permission is hereby granted, free of charge, to any person obtaining
    -# a copy of this software and associated documentation files (the
    -# "Software"), to deal in the Software without restriction, including
    -# without limitation the rights to use, copy, modify, merge, publish,
    -# distribute, sublicense, and/or sell copies of the Software, and to
    -# permit persons to whom the Software is furnished to do so, subject to
    -# the following conditions:
    -#
    -# The above copyright notice and this permission notice shall be
    -# included in all copies or substantial portions of the Software.
    -#
    -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    -#
    -
    -__doc__ = \
    -"""
    -pyparsing module - Classes and methods to define and execute parsing grammars
    -=============================================================================
    -
    -The pyparsing module is an alternative approach to creating and executing simple grammars,
    -vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
    -don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
    -provides a library of classes that you use to construct the grammar directly in Python.
    -
    -Here is a program to parse "Hello, World!" (or any greeting of the form 
    -C{", !"}), built up using L{Word}, L{Literal}, and L{And} elements 
    -(L{'+'} operator gives L{And} expressions, strings are auto-converted to
    -L{Literal} expressions)::
    -
    -    from pyparsing import Word, alphas
    -
    -    # define grammar of a greeting
    -    greet = Word(alphas) + "," + Word(alphas) + "!"
    -
    -    hello = "Hello, World!"
    -    print (hello, "->", greet.parseString(hello))
    -
    -The program outputs the following::
    -
    -    Hello, World! -> ['Hello', ',', 'World', '!']
    -
    -The Python representation of the grammar is quite readable, owing to the self-explanatory
    -class names, and the use of '+', '|' and '^' operators.
    -
    -The L{ParseResults} object returned from L{ParserElement.parseString} can be accessed as a nested list, a dictionary, or an
    -object with named attributes.
    -
    -The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
    - - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
    - - quoted strings
    - - embedded comments
    -
    -
    -Getting Started -
    ------------------
    -Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing
    -classes inherit from. Use the docstrings for examples of how to:
    - - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes
    - - construct character word-group expressions using the L{Word} class
    - - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes
    - - use L{'+'}, L{'|'}, L{'^'}, and L{'&'} operators to combine simple expressions into more complex ones
    - - associate names with your parsed results using L{ParserElement.setResultsName}
    - - find some helpful expression short-cuts like L{delimitedList} and L{oneOf}
    - - find more useful common expressions in the L{pyparsing_common} namespace class
    -"""
    -
    -__version__ = "2.2.1"
    -__versionTime__ = "18 Sep 2018 00:49 UTC"
    -__author__ = "Paul McGuire "
    -
    -import string
    -from weakref import ref as wkref
    -import copy
    -import sys
    -import warnings
    -import re
    -import sre_constants
    -import collections
    -import pprint
    -import traceback
    -import types
    -from datetime import datetime
    -
    -try:
    -    from _thread import RLock
    -except ImportError:
    -    from threading import RLock
    -
    -try:
    -    # Python 3
    -    from collections.abc import Iterable
    -    from collections.abc import MutableMapping
    -except ImportError:
    -    # Python 2.7
    -    from collections import Iterable
    -    from collections import MutableMapping
    -
    -try:
    -    from collections import OrderedDict as _OrderedDict
    -except ImportError:
    -    try:
    -        from ordereddict import OrderedDict as _OrderedDict
    -    except ImportError:
    -        _OrderedDict = None
    -
    -#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
    -
    -__all__ = [
    -'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
    -'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
    -'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
    -'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
    -'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
    -'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
    -'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
    -'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
    -'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
    -'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
    -'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
    -'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
    -'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
    -'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
    -'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
    -'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
    -'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
    -'CloseMatch', 'tokenMap', 'pyparsing_common',
    -]
    -
    -system_version = tuple(sys.version_info)[:3]
    -PY_3 = system_version[0] == 3
    -if PY_3:
    -    _MAX_INT = sys.maxsize
    -    basestring = str
    -    unichr = chr
    -    _ustr = str
    -
    -    # build list of single arg builtins, that can be used as parse actions
    -    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
    -
    -else:
    -    _MAX_INT = sys.maxint
    -    range = xrange
    -
    -    def _ustr(obj):
    -        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
    -           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
    -           then < returns the unicode object | encodes it with the default encoding | ... >.
    -        """
    -        if isinstance(obj,unicode):
    -            return obj
    -
    -        try:
    -            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
    -            # it won't break any existing code.
    -            return str(obj)
    -
    -        except UnicodeEncodeError:
    -            # Else encode it
    -            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
    -            xmlcharref = Regex(r'&#\d+;')
    -            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
    -            return xmlcharref.transformString(ret)
    -
    -    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
    -    singleArgBuiltins = []
    -    import __builtin__
    -    for fname in "sum len sorted reversed list tuple set any all min max".split():
    -        try:
    -            singleArgBuiltins.append(getattr(__builtin__,fname))
    -        except AttributeError:
    -            continue
    -            
    -_generatorType = type((y for y in range(1)))
    - 
    -def _xml_escape(data):
    -    """Escape &, <, >, ", ', etc. in a string of data."""
    -
    -    # ampersand must be replaced first
    -    from_symbols = '&><"\''
    -    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
    -    for from_,to_ in zip(from_symbols, to_symbols):
    -        data = data.replace(from_, to_)
    -    return data
    -
    -class _Constants(object):
    -    pass
    -
    -alphas     = string.ascii_uppercase + string.ascii_lowercase
    -nums       = "0123456789"
    -hexnums    = nums + "ABCDEFabcdef"
    -alphanums  = alphas + nums
    -_bslash    = chr(92)
    -printables = "".join(c for c in string.printable if c not in string.whitespace)
    -
    -class ParseBaseException(Exception):
    -    """base exception class for all parsing runtime exceptions"""
    -    # Performance tuning: we construct a *lot* of these, so keep this
    -    # constructor as small and fast as possible
    -    def __init__( self, pstr, loc=0, msg=None, elem=None ):
    -        self.loc = loc
    -        if msg is None:
    -            self.msg = pstr
    -            self.pstr = ""
    -        else:
    -            self.msg = msg
    -            self.pstr = pstr
    -        self.parserElement = elem
    -        self.args = (pstr, loc, msg)
    -
    -    @classmethod
    -    def _from_exception(cls, pe):
    -        """
    -        internal factory method to simplify creating one type of ParseException 
    -        from another - avoids having __init__ signature conflicts among subclasses
    -        """
    -        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)
    -
    -    def __getattr__( self, aname ):
    -        """supported attributes by name are:
    -            - lineno - returns the line number of the exception text
    -            - col - returns the column number of the exception text
    -            - line - returns the line containing the exception text
    -        """
    -        if( aname == "lineno" ):
    -            return lineno( self.loc, self.pstr )
    -        elif( aname in ("col", "column") ):
    -            return col( self.loc, self.pstr )
    -        elif( aname == "line" ):
    -            return line( self.loc, self.pstr )
    -        else:
    -            raise AttributeError(aname)
    -
    -    def __str__( self ):
    -        return "%s (at char %d), (line:%d, col:%d)" % \
    -                ( self.msg, self.loc, self.lineno, self.column )
    -    def __repr__( self ):
    -        return _ustr(self)
    -    def markInputline( self, markerString = ">!<" ):
    -        """Extracts the exception line from the input string, and marks
    -           the location of the exception with a special symbol.
    -        """
    -        line_str = self.line
    -        line_column = self.column - 1
    -        if markerString:
    -            line_str = "".join((line_str[:line_column],
    -                                markerString, line_str[line_column:]))
    -        return line_str.strip()
    -    def __dir__(self):
    -        return "lineno col line".split() + dir(type(self))
    -
    -class ParseException(ParseBaseException):
    -    """
    -    Exception thrown when parse expressions don't match class;
    -    supported attributes by name are:
    -     - lineno - returns the line number of the exception text
    -     - col - returns the column number of the exception text
    -     - line - returns the line containing the exception text
    -        
    -    Example::
    -        try:
    -            Word(nums).setName("integer").parseString("ABC")
    -        except ParseException as pe:
    -            print(pe)
    -            print("column: {}".format(pe.col))
    -            
    -    prints::
    -       Expected integer (at char 0), (line:1, col:1)
    -        column: 1
    -    """
    -    pass
    -
    -class ParseFatalException(ParseBaseException):
    -    """user-throwable exception thrown when inconsistent parse content
    -       is found; stops all parsing immediately"""
    -    pass
    -
    -class ParseSyntaxException(ParseFatalException):
    -    """just like L{ParseFatalException}, but thrown internally when an
    -       L{ErrorStop} ('-' operator) indicates that parsing is to stop 
    -       immediately because an unbacktrackable syntax error has been found"""
    -    pass
    -
    -#~ class ReparseException(ParseBaseException):
    -    #~ """Experimental class - parse actions can raise this exception to cause
    -       #~ pyparsing to reparse the input string:
    -        #~ - with a modified input string, and/or
    -        #~ - with a modified start location
    -       #~ Set the values of the ReparseException in the constructor, and raise the
    -       #~ exception in a parse action to cause pyparsing to use the new string/location.
    -       #~ Setting the values as None causes no change to be made.
    -       #~ """
    -    #~ def __init_( self, newstring, restartLoc ):
    -        #~ self.newParseText = newstring
    -        #~ self.reparseLoc = restartLoc
    -
    -class RecursiveGrammarException(Exception):
    -    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
    -    def __init__( self, parseElementList ):
    -        self.parseElementTrace = parseElementList
    -
    -    def __str__( self ):
    -        return "RecursiveGrammarException: %s" % self.parseElementTrace
    -
    -class _ParseResultsWithOffset(object):
    -    def __init__(self,p1,p2):
    -        self.tup = (p1,p2)
    -    def __getitem__(self,i):
    -        return self.tup[i]
    -    def __repr__(self):
    -        return repr(self.tup[0])
    -    def setOffset(self,i):
    -        self.tup = (self.tup[0],i)
    -
    -class ParseResults(object):
    -    """
    -    Structured parse results, to provide multiple means of access to the parsed data:
    -       - as a list (C{len(results)})
    -       - by list index (C{results[0], results[1]}, etc.)
    -       - by attribute (C{results.} - see L{ParserElement.setResultsName})
    -
    -    Example::
    -        integer = Word(nums)
    -        date_str = (integer.setResultsName("year") + '/' 
    -                        + integer.setResultsName("month") + '/' 
    -                        + integer.setResultsName("day"))
    -        # equivalent form:
    -        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
    -
    -        # parseString returns a ParseResults object
    -        result = date_str.parseString("1999/12/31")
    -
    -        def test(s, fn=repr):
    -            print("%s -> %s" % (s, fn(eval(s))))
    -        test("list(result)")
    -        test("result[0]")
    -        test("result['month']")
    -        test("result.day")
    -        test("'month' in result")
    -        test("'minutes' in result")
    -        test("result.dump()", str)
    -    prints::
    -        list(result) -> ['1999', '/', '12', '/', '31']
    -        result[0] -> '1999'
    -        result['month'] -> '12'
    -        result.day -> '31'
    -        'month' in result -> True
    -        'minutes' in result -> False
    -        result.dump() -> ['1999', '/', '12', '/', '31']
    -        - day: 31
    -        - month: 12
    -        - year: 1999
    -    """
    -    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
    -        if isinstance(toklist, cls):
    -            return toklist
    -        retobj = object.__new__(cls)
    -        retobj.__doinit = True
    -        return retobj
    -
    -    # Performance tuning: we construct a *lot* of these, so keep this
    -    # constructor as small and fast as possible
    -    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
    -        if self.__doinit:
    -            self.__doinit = False
    -            self.__name = None
    -            self.__parent = None
    -            self.__accumNames = {}
    -            self.__asList = asList
    -            self.__modal = modal
    -            if toklist is None:
    -                toklist = []
    -            if isinstance(toklist, list):
    -                self.__toklist = toklist[:]
    -            elif isinstance(toklist, _generatorType):
    -                self.__toklist = list(toklist)
    -            else:
    -                self.__toklist = [toklist]
    -            self.__tokdict = dict()
    -
    -        if name is not None and name:
    -            if not modal:
    -                self.__accumNames[name] = 0
    -            if isinstance(name,int):
    -                name = _ustr(name) # will always return a str, but use _ustr for consistency
    -            self.__name = name
    -            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
    -                if isinstance(toklist,basestring):
    -                    toklist = [ toklist ]
    -                if asList:
    -                    if isinstance(toklist,ParseResults):
    -                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
    -                    else:
    -                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
    -                    self[name].__name = name
    -                else:
    -                    try:
    -                        self[name] = toklist[0]
    -                    except (KeyError,TypeError,IndexError):
    -                        self[name] = toklist
    -
    -    def __getitem__( self, i ):
    -        if isinstance( i, (int,slice) ):
    -            return self.__toklist[i]
    -        else:
    -            if i not in self.__accumNames:
    -                return self.__tokdict[i][-1][0]
    -            else:
    -                return ParseResults([ v[0] for v in self.__tokdict[i] ])
    -
    -    def __setitem__( self, k, v, isinstance=isinstance ):
    -        if isinstance(v,_ParseResultsWithOffset):
    -            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
    -            sub = v[0]
    -        elif isinstance(k,(int,slice)):
    -            self.__toklist[k] = v
    -            sub = v
    -        else:
    -            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
    -            sub = v
    -        if isinstance(sub,ParseResults):
    -            sub.__parent = wkref(self)
    -
    -    def __delitem__( self, i ):
    -        if isinstance(i,(int,slice)):
    -            mylen = len( self.__toklist )
    -            del self.__toklist[i]
    -
    -            # convert int to slice
    -            if isinstance(i, int):
    -                if i < 0:
    -                    i += mylen
    -                i = slice(i, i+1)
    -            # get removed indices
    -            removed = list(range(*i.indices(mylen)))
    -            removed.reverse()
    -            # fixup indices in token dictionary
    -            for name,occurrences in self.__tokdict.items():
    -                for j in removed:
    -                    for k, (value, position) in enumerate(occurrences):
    -                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
    -        else:
    -            del self.__tokdict[i]
    -
    -    def __contains__( self, k ):
    -        return k in self.__tokdict
    -
    -    def __len__( self ): return len( self.__toklist )
    -    def __bool__(self): return ( not not self.__toklist )
    -    __nonzero__ = __bool__
    -    def __iter__( self ): return iter( self.__toklist )
    -    def __reversed__( self ): return iter( self.__toklist[::-1] )
    -    def _iterkeys( self ):
    -        if hasattr(self.__tokdict, "iterkeys"):
    -            return self.__tokdict.iterkeys()
    -        else:
    -            return iter(self.__tokdict)
    -
    -    def _itervalues( self ):
    -        return (self[k] for k in self._iterkeys())
    -            
    -    def _iteritems( self ):
    -        return ((k, self[k]) for k in self._iterkeys())
    -
    -    if PY_3:
    -        keys = _iterkeys       
    -        """Returns an iterator of all named result keys (Python 3.x only)."""
    -
    -        values = _itervalues
    -        """Returns an iterator of all named result values (Python 3.x only)."""
    -
    -        items = _iteritems
    -        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
    -
    -    else:
    -        iterkeys = _iterkeys
    -        """Returns an iterator of all named result keys (Python 2.x only)."""
    -
    -        itervalues = _itervalues
    -        """Returns an iterator of all named result values (Python 2.x only)."""
    -
    -        iteritems = _iteritems
    -        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
    -
    -        def keys( self ):
    -            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
    -            return list(self.iterkeys())
    -
    -        def values( self ):
    -            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
    -            return list(self.itervalues())
    -                
    -        def items( self ):
    -            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
    -            return list(self.iteritems())
    -
    -    def haskeys( self ):
    -        """Since keys() returns an iterator, this method is helpful in bypassing
    -           code that looks for the existence of any defined results names."""
    -        return bool(self.__tokdict)
    -        
    -    def pop( self, *args, **kwargs):
    -        """
    -        Removes and returns item at specified index (default=C{last}).
    -        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
    -        argument or an integer argument, it will use C{list} semantics
    -        and pop tokens from the list of parsed tokens. If passed a 
    -        non-integer argument (most likely a string), it will use C{dict}
    -        semantics and pop the corresponding value from any defined 
    -        results names. A second default return value argument is 
    -        supported, just as in C{dict.pop()}.
    -
    -        Example::
    -            def remove_first(tokens):
    -                tokens.pop(0)
    -            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
    -            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
    -
    -            label = Word(alphas)
    -            patt = label("LABEL") + OneOrMore(Word(nums))
    -            print(patt.parseString("AAB 123 321").dump())
    -
    -            # Use pop() in a parse action to remove named result (note that corresponding value is not
    -            # removed from list form of results)
    -            def remove_LABEL(tokens):
    -                tokens.pop("LABEL")
    -                return tokens
    -            patt.addParseAction(remove_LABEL)
    -            print(patt.parseString("AAB 123 321").dump())
    -        prints::
    -            ['AAB', '123', '321']
    -            - LABEL: AAB
    -
    -            ['AAB', '123', '321']
    -        """
    -        if not args:
    -            args = [-1]
    -        for k,v in kwargs.items():
    -            if k == 'default':
    -                args = (args[0], v)
    -            else:
    -                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
    -        if (isinstance(args[0], int) or 
    -                        len(args) == 1 or 
    -                        args[0] in self):
    -            index = args[0]
    -            ret = self[index]
    -            del self[index]
    -            return ret
    -        else:
    -            defaultvalue = args[1]
    -            return defaultvalue
    -
    -    def get(self, key, defaultValue=None):
    -        """
    -        Returns named result matching the given key, or if there is no
    -        such name, then returns the given C{defaultValue} or C{None} if no
    -        C{defaultValue} is specified.
    -
    -        Similar to C{dict.get()}.
    -        
    -        Example::
    -            integer = Word(nums)
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
    -
    -            result = date_str.parseString("1999/12/31")
    -            print(result.get("year")) # -> '1999'
    -            print(result.get("hour", "not specified")) # -> 'not specified'
    -            print(result.get("hour")) # -> None
    -        """
    -        if key in self:
    -            return self[key]
    -        else:
    -            return defaultValue
    -
    -    def insert( self, index, insStr ):
    -        """
    -        Inserts new element at location index in the list of parsed tokens.
    -        
    -        Similar to C{list.insert()}.
    -
    -        Example::
    -            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
    -
    -            # use a parse action to insert the parse location in the front of the parsed results
    -            def insert_locn(locn, tokens):
    -                tokens.insert(0, locn)
    -            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
    -        """
    -        self.__toklist.insert(index, insStr)
    -        # fixup indices in token dictionary
    -        for name,occurrences in self.__tokdict.items():
    -            for k, (value, position) in enumerate(occurrences):
    -                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
    -
    -    def append( self, item ):
    -        """
    -        Add single element to end of ParseResults list of elements.
    -
    -        Example::
    -            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
    -            
    -            # use a parse action to compute the sum of the parsed integers, and add it to the end
    -            def append_sum(tokens):
    -                tokens.append(sum(map(int, tokens)))
    -            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
    -        """
    -        self.__toklist.append(item)
    -
    -    def extend( self, itemseq ):
    -        """
    -        Add sequence of elements to end of ParseResults list of elements.
    -
    -        Example::
    -            patt = OneOrMore(Word(alphas))
    -            
    -            # use a parse action to append the reverse of the matched strings, to make a palindrome
    -            def make_palindrome(tokens):
    -                tokens.extend(reversed([t[::-1] for t in tokens]))
    -                return ''.join(tokens)
    -            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
    -        """
    -        if isinstance(itemseq, ParseResults):
    -            self += itemseq
    -        else:
    -            self.__toklist.extend(itemseq)
    -
    -    def clear( self ):
    -        """
    -        Clear all elements and results names.
    -        """
    -        del self.__toklist[:]
    -        self.__tokdict.clear()
    -
    -    def __getattr__( self, name ):
    -        try:
    -            return self[name]
    -        except KeyError:
    -            return ""
    -            
    -        if name in self.__tokdict:
    -            if name not in self.__accumNames:
    -                return self.__tokdict[name][-1][0]
    -            else:
    -                return ParseResults([ v[0] for v in self.__tokdict[name] ])
    -        else:
    -            return ""
    -
    -    def __add__( self, other ):
    -        ret = self.copy()
    -        ret += other
    -        return ret
    -
    -    def __iadd__( self, other ):
    -        if other.__tokdict:
    -            offset = len(self.__toklist)
    -            addoffset = lambda a: offset if a<0 else a+offset
    -            otheritems = other.__tokdict.items()
    -            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
    -                                for (k,vlist) in otheritems for v in vlist]
    -            for k,v in otherdictitems:
    -                self[k] = v
    -                if isinstance(v[0],ParseResults):
    -                    v[0].__parent = wkref(self)
    -            
    -        self.__toklist += other.__toklist
    -        self.__accumNames.update( other.__accumNames )
    -        return self
    -
    -    def __radd__(self, other):
    -        if isinstance(other,int) and other == 0:
    -            # useful for merging many ParseResults using sum() builtin
    -            return self.copy()
    -        else:
    -            # this may raise a TypeError - so be it
    -            return other + self
    -        
    -    def __repr__( self ):
    -        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
    -
    -    def __str__( self ):
    -        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
    -
    -    def _asStringList( self, sep='' ):
    -        out = []
    -        for item in self.__toklist:
    -            if out and sep:
    -                out.append(sep)
    -            if isinstance( item, ParseResults ):
    -                out += item._asStringList()
    -            else:
    -                out.append( _ustr(item) )
    -        return out
    -
    -    def asList( self ):
    -        """
    -        Returns the parse results as a nested list of matching tokens, all converted to strings.
    -
    -        Example::
    -            patt = OneOrMore(Word(alphas))
    -            result = patt.parseString("sldkj lsdkj sldkj")
    -            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
    -            print(type(result), result) # ->  ['sldkj', 'lsdkj', 'sldkj']
    -            
    -            # Use asList() to create an actual list
    -            result_list = result.asList()
    -            print(type(result_list), result_list) # ->  ['sldkj', 'lsdkj', 'sldkj']
    -        """
    -        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
    -
    -    def asDict( self ):
    -        """
    -        Returns the named parse results as a nested dictionary.
    -
    -        Example::
    -            integer = Word(nums)
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
    -            
    -            result = date_str.parseString('12/31/1999')
    -            print(type(result), repr(result)) # ->  (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
    -            
    -            result_dict = result.asDict()
    -            print(type(result_dict), repr(result_dict)) # ->  {'day': '1999', 'year': '12', 'month': '31'}
    -
    -            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
    -            import json
    -            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
    -            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
    -        """
    -        if PY_3:
    -            item_fn = self.items
    -        else:
    -            item_fn = self.iteritems
    -            
    -        def toItem(obj):
    -            if isinstance(obj, ParseResults):
    -                if obj.haskeys():
    -                    return obj.asDict()
    -                else:
    -                    return [toItem(v) for v in obj]
    -            else:
    -                return obj
    -                
    -        return dict((k,toItem(v)) for k,v in item_fn())
    -
    -    def copy( self ):
    -        """
    -        Returns a new copy of a C{ParseResults} object.
    -        """
    -        ret = ParseResults( self.__toklist )
    -        ret.__tokdict = self.__tokdict.copy()
    -        ret.__parent = self.__parent
    -        ret.__accumNames.update( self.__accumNames )
    -        ret.__name = self.__name
    -        return ret
    -
    -    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
    -        """
    -        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
    -        """
    -        nl = "\n"
    -        out = []
    -        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
    -                                                            for v in vlist)
    -        nextLevelIndent = indent + "  "
    -
    -        # collapse out indents if formatting is not desired
    -        if not formatted:
    -            indent = ""
    -            nextLevelIndent = ""
    -            nl = ""
    -
    -        selfTag = None
    -        if doctag is not None:
    -            selfTag = doctag
    -        else:
    -            if self.__name:
    -                selfTag = self.__name
    -
    -        if not selfTag:
    -            if namedItemsOnly:
    -                return ""
    -            else:
    -                selfTag = "ITEM"
    -
    -        out += [ nl, indent, "<", selfTag, ">" ]
    -
    -        for i,res in enumerate(self.__toklist):
    -            if isinstance(res,ParseResults):
    -                if i in namedItems:
    -                    out += [ res.asXML(namedItems[i],
    -                                        namedItemsOnly and doctag is None,
    -                                        nextLevelIndent,
    -                                        formatted)]
    -                else:
    -                    out += [ res.asXML(None,
    -                                        namedItemsOnly and doctag is None,
    -                                        nextLevelIndent,
    -                                        formatted)]
    -            else:
    -                # individual token, see if there is a name for it
    -                resTag = None
    -                if i in namedItems:
    -                    resTag = namedItems[i]
    -                if not resTag:
    -                    if namedItemsOnly:
    -                        continue
    -                    else:
    -                        resTag = "ITEM"
    -                xmlBodyText = _xml_escape(_ustr(res))
    -                out += [ nl, nextLevelIndent, "<", resTag, ">",
    -                                                xmlBodyText,
    -                                                "" ]
    -
    -        out += [ nl, indent, "" ]
    -        return "".join(out)
    -
    -    def __lookup(self,sub):
    -        for k,vlist in self.__tokdict.items():
    -            for v,loc in vlist:
    -                if sub is v:
    -                    return k
    -        return None
    -
    -    def getName(self):
    -        r"""
    -        Returns the results name for this token expression. Useful when several 
    -        different expressions might match at a particular location.
    -
    -        Example::
    -            integer = Word(nums)
    -            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
    -            house_number_expr = Suppress('#') + Word(nums, alphanums)
    -            user_data = (Group(house_number_expr)("house_number") 
    -                        | Group(ssn_expr)("ssn")
    -                        | Group(integer)("age"))
    -            user_info = OneOrMore(user_data)
    -            
    -            result = user_info.parseString("22 111-22-3333 #221B")
    -            for item in result:
    -                print(item.getName(), ':', item[0])
    -        prints::
    -            age : 22
    -            ssn : 111-22-3333
    -            house_number : 221B
    -        """
    -        if self.__name:
    -            return self.__name
    -        elif self.__parent:
    -            par = self.__parent()
    -            if par:
    -                return par.__lookup(self)
    -            else:
    -                return None
    -        elif (len(self) == 1 and
    -               len(self.__tokdict) == 1 and
    -               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
    -            return next(iter(self.__tokdict.keys()))
    -        else:
    -            return None
    -
    -    def dump(self, indent='', depth=0, full=True):
    -        """
    -        Diagnostic method for listing out the contents of a C{ParseResults}.
    -        Accepts an optional C{indent} argument so that this string can be embedded
    -        in a nested display of other data.
    -
    -        Example::
    -            integer = Word(nums)
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
    -            
    -            result = date_str.parseString('12/31/1999')
    -            print(result.dump())
    -        prints::
    -            ['12', '/', '31', '/', '1999']
    -            - day: 1999
    -            - month: 31
    -            - year: 12
    -        """
    -        out = []
    -        NL = '\n'
    -        out.append( indent+_ustr(self.asList()) )
    -        if full:
    -            if self.haskeys():
    -                items = sorted((str(k), v) for k,v in self.items())
    -                for k,v in items:
    -                    if out:
    -                        out.append(NL)
    -                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
    -                    if isinstance(v,ParseResults):
    -                        if v:
    -                            out.append( v.dump(indent,depth+1) )
    -                        else:
    -                            out.append(_ustr(v))
    -                    else:
    -                        out.append(repr(v))
    -            elif any(isinstance(vv,ParseResults) for vv in self):
    -                v = self
    -                for i,vv in enumerate(v):
    -                    if isinstance(vv,ParseResults):
    -                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
    -                    else:
    -                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
    -            
    -        return "".join(out)
    -
    -    def pprint(self, *args, **kwargs):
    -        """
    -        Pretty-printer for parsed results as a list, using the C{pprint} module.
    -        Accepts additional positional or keyword args as defined for the 
    -        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
    -
    -        Example::
    -            ident = Word(alphas, alphanums)
    -            num = Word(nums)
    -            func = Forward()
    -            term = ident | num | Group('(' + func + ')')
    -            func <<= ident + Group(Optional(delimitedList(term)))
    -            result = func.parseString("fna a,b,(fnb c,d,200),100")
    -            result.pprint(width=40)
    -        prints::
    -            ['fna',
    -             ['a',
    -              'b',
    -              ['(', 'fnb', ['c', 'd', '200'], ')'],
    -              '100']]
    -        """
    -        pprint.pprint(self.asList(), *args, **kwargs)
    -
    -    # add support for pickle protocol
    -    def __getstate__(self):
    -        return ( self.__toklist,
    -                 ( self.__tokdict.copy(),
    -                   self.__parent is not None and self.__parent() or None,
    -                   self.__accumNames,
    -                   self.__name ) )
    -
    -    def __setstate__(self,state):
    -        self.__toklist = state[0]
    -        (self.__tokdict,
    -         par,
    -         inAccumNames,
    -         self.__name) = state[1]
    -        self.__accumNames = {}
    -        self.__accumNames.update(inAccumNames)
    -        if par is not None:
    -            self.__parent = wkref(par)
    -        else:
    -            self.__parent = None
    -
    -    def __getnewargs__(self):
    -        return self.__toklist, self.__name, self.__asList, self.__modal
    -
    -    def __dir__(self):
    -        return (dir(type(self)) + list(self.keys()))
    -
    -MutableMapping.register(ParseResults)
    -
    -def col (loc,strg):
    -    """Returns current column within a string, counting newlines as line separators.
    -   The first column is number 1.
    -
    -   Note: the default parsing behavior is to expand tabs in the input string
    -   before starting the parsing process.  See L{I{ParserElement.parseString}} for more information
    -   on parsing strings containing C{}s, and suggested methods to maintain a
    -   consistent view of the parsed string, the parse location, and line and column
    -   positions within the parsed string.
    -   """
    -    s = strg
    -    return 1 if 0} for more information
    -   on parsing strings containing C{}s, and suggested methods to maintain a
    -   consistent view of the parsed string, the parse location, and line and column
    -   positions within the parsed string.
    -   """
    -    return strg.count("\n",0,loc) + 1
    -
    -def line( loc, strg ):
    -    """Returns the line of text containing loc within a string, counting newlines as line separators.
    -       """
    -    lastCR = strg.rfind("\n", 0, loc)
    -    nextCR = strg.find("\n", loc)
    -    if nextCR >= 0:
    -        return strg[lastCR+1:nextCR]
    -    else:
    -        return strg[lastCR+1:]
    -
    -def _defaultStartDebugAction( instring, loc, expr ):
    -    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
    -
    -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
    -    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
    -
    -def _defaultExceptionDebugAction( instring, loc, expr, exc ):
    -    print ("Exception raised:" + _ustr(exc))
    -
    -def nullDebugAction(*args):
    -    """'Do-nothing' debug action, to suppress debugging output during parsing."""
    -    pass
    -
    -# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
    -#~ 'decorator to trim function calls to match the arity of the target'
    -#~ def _trim_arity(func, maxargs=3):
    -    #~ if func in singleArgBuiltins:
    -        #~ return lambda s,l,t: func(t)
    -    #~ limit = 0
    -    #~ foundArity = False
    -    #~ def wrapper(*args):
    -        #~ nonlocal limit,foundArity
    -        #~ while 1:
    -            #~ try:
    -                #~ ret = func(*args[limit:])
    -                #~ foundArity = True
    -                #~ return ret
    -            #~ except TypeError:
    -                #~ if limit == maxargs or foundArity:
    -                    #~ raise
    -                #~ limit += 1
    -                #~ continue
    -    #~ return wrapper
    -
    -# this version is Python 2.x-3.x cross-compatible
    -'decorator to trim function calls to match the arity of the target'
    -def _trim_arity(func, maxargs=2):
    -    if func in singleArgBuiltins:
    -        return lambda s,l,t: func(t)
    -    limit = [0]
    -    foundArity = [False]
    -    
    -    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
    -    if system_version[:2] >= (3,5):
    -        def extract_stack(limit=0):
    -            # special handling for Python 3.5.0 - extra deep call stack by 1
    -            offset = -3 if system_version == (3,5,0) else -2
    -            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
    -            return [frame_summary[:2]]
    -        def extract_tb(tb, limit=0):
    -            frames = traceback.extract_tb(tb, limit=limit)
    -            frame_summary = frames[-1]
    -            return [frame_summary[:2]]
    -    else:
    -        extract_stack = traceback.extract_stack
    -        extract_tb = traceback.extract_tb
    -    
    -    # synthesize what would be returned by traceback.extract_stack at the call to 
    -    # user's parse action 'func', so that we don't incur call penalty at parse time
    -    
    -    LINE_DIFF = 6
    -    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
    -    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
    -    this_line = extract_stack(limit=2)[-1]
    -    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
    -
    -    def wrapper(*args):
    -        while 1:
    -            try:
    -                ret = func(*args[limit[0]:])
    -                foundArity[0] = True
    -                return ret
    -            except TypeError:
    -                # re-raise TypeErrors if they did not come from our arity testing
    -                if foundArity[0]:
    -                    raise
    -                else:
    -                    try:
    -                        tb = sys.exc_info()[-1]
    -                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
    -                            raise
    -                    finally:
    -                        del tb
    -
    -                if limit[0] <= maxargs:
    -                    limit[0] += 1
    -                    continue
    -                raise
    -
    -    # copy func name to wrapper for sensible debug output
    -    func_name = ""
    -    try:
    -        func_name = getattr(func, '__name__', 
    -                            getattr(func, '__class__').__name__)
    -    except Exception:
    -        func_name = str(func)
    -    wrapper.__name__ = func_name
    -
    -    return wrapper
    -
    -class ParserElement(object):
    -    """Abstract base level parser element class."""
    -    DEFAULT_WHITE_CHARS = " \n\t\r"
    -    verbose_stacktrace = False
    -
    -    @staticmethod
    -    def setDefaultWhitespaceChars( chars ):
    -        r"""
    -        Overrides the default whitespace chars
    -
    -        Example::
    -            # default whitespace chars are space,  and newline
    -            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
    -            
    -            # change to just treat newline as significant
    -            ParserElement.setDefaultWhitespaceChars(" \t")
    -            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
    -        """
    -        ParserElement.DEFAULT_WHITE_CHARS = chars
    -
    -    @staticmethod
    -    def inlineLiteralsUsing(cls):
    -        """
    -        Set class to be used for inclusion of string literals into a parser.
    -        
    -        Example::
    -            # default literal class used is Literal
    -            integer = Word(nums)
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
    -
    -            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
    -
    -
    -            # change to Suppress
    -            ParserElement.inlineLiteralsUsing(Suppress)
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
    -
    -            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
    -        """
    -        ParserElement._literalStringClass = cls
    -
    -    def __init__( self, savelist=False ):
    -        self.parseAction = list()
    -        self.failAction = None
    -        #~ self.name = ""  # don't define self.name, let subclasses try/except upcall
    -        self.strRepr = None
    -        self.resultsName = None
    -        self.saveAsList = savelist
    -        self.skipWhitespace = True
    -        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
    -        self.copyDefaultWhiteChars = True
    -        self.mayReturnEmpty = False # used when checking for left-recursion
    -        self.keepTabs = False
    -        self.ignoreExprs = list()
    -        self.debug = False
    -        self.streamlined = False
    -        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
    -        self.errmsg = ""
    -        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
    -        self.debugActions = ( None, None, None ) #custom debug actions
    -        self.re = None
    -        self.callPreparse = True # used to avoid redundant calls to preParse
    -        self.callDuringTry = False
    -
    -    def copy( self ):
    -        """
    -        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
    -        for the same parsing pattern, using copies of the original parse element.
    -        
    -        Example::
    -            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
    -            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
    -            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
    -            
    -            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
    -        prints::
    -            [5120, 100, 655360, 268435456]
    -        Equivalent form of C{expr.copy()} is just C{expr()}::
    -            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
    -        """
    -        cpy = copy.copy( self )
    -        cpy.parseAction = self.parseAction[:]
    -        cpy.ignoreExprs = self.ignoreExprs[:]
    -        if self.copyDefaultWhiteChars:
    -            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
    -        return cpy
    -
    -    def setName( self, name ):
    -        """
    -        Define name for this expression, makes debugging and exception messages clearer.
    -        
    -        Example::
    -            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
    -            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
    -        """
    -        self.name = name
    -        self.errmsg = "Expected " + self.name
    -        if hasattr(self,"exception"):
    -            self.exception.msg = self.errmsg
    -        return self
    -
    -    def setResultsName( self, name, listAllMatches=False ):
    -        """
    -        Define name for referencing matching tokens as a nested attribute
    -        of the returned parse results.
    -        NOTE: this returns a *copy* of the original C{ParserElement} object;
    -        this is so that the client can define a basic element, such as an
    -        integer, and reference it in multiple places with different names.
    -
    -        You can also set results names using the abbreviated syntax,
    -        C{expr("name")} in place of C{expr.setResultsName("name")} - 
    -        see L{I{__call__}<__call__>}.
    -
    -        Example::
    -            date_str = (integer.setResultsName("year") + '/' 
    -                        + integer.setResultsName("month") + '/' 
    -                        + integer.setResultsName("day"))
    -
    -            # equivalent form:
    -            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
    -        """
    -        newself = self.copy()
    -        if name.endswith("*"):
    -            name = name[:-1]
    -            listAllMatches=True
    -        newself.resultsName = name
    -        newself.modalResults = not listAllMatches
    -        return newself
    -
    -    def setBreak(self,breakFlag = True):
    -        """Method to invoke the Python pdb debugger when this element is
    -           about to be parsed. Set C{breakFlag} to True to enable, False to
    -           disable.
    -        """
    -        if breakFlag:
    -            _parseMethod = self._parse
    -            def breaker(instring, loc, doActions=True, callPreParse=True):
    -                import pdb
    -                pdb.set_trace()
    -                return _parseMethod( instring, loc, doActions, callPreParse )
    -            breaker._originalParseMethod = _parseMethod
    -            self._parse = breaker
    -        else:
    -            if hasattr(self._parse,"_originalParseMethod"):
    -                self._parse = self._parse._originalParseMethod
    -        return self
    -
    -    def setParseAction( self, *fns, **kwargs ):
    -        """
    -        Define one or more actions to perform when successfully matching parse element definition.
    -        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
    -        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
    -         - s   = the original string being parsed (see note below)
    -         - loc = the location of the matching substring
    -         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
    -        If the functions in fns modify the tokens, they can return them as the return
    -        value from fn, and the modified list of tokens will replace the original.
    -        Otherwise, fn does not need to return any value.
    -
    -        Optional keyword arguments:
    -         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
    -
    -        Note: the default parsing behavior is to expand tabs in the input string
    -        before starting the parsing process.  See L{I{parseString}} for more information
    -        on parsing strings containing C{}s, and suggested methods to maintain a
    -        consistent view of the parsed string, the parse location, and line and column
    -        positions within the parsed string.
    -        
    -        Example::
    -            integer = Word(nums)
    -            date_str = integer + '/' + integer + '/' + integer
    -
    -            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
    -
    -            # use parse action to convert to ints at parse time
    -            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
    -            date_str = integer + '/' + integer + '/' + integer
    -
    -            # note that integer fields are now ints, not strings
    -            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
    -        """
    -        self.parseAction = list(map(_trim_arity, list(fns)))
    -        self.callDuringTry = kwargs.get("callDuringTry", False)
    -        return self
    -
    -    def addParseAction( self, *fns, **kwargs ):
    -        """
    -        Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}}.
    -        
    -        See examples in L{I{copy}}.
    -        """
    -        self.parseAction += list(map(_trim_arity, list(fns)))
    -        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
    -        return self
    -
    -    def addCondition(self, *fns, **kwargs):
    -        """Add a boolean predicate function to expression's list of parse actions. See 
    -        L{I{setParseAction}} for function call signatures. Unlike C{setParseAction}, 
    -        functions passed to C{addCondition} need to return boolean success/fail of the condition.
    -
    -        Optional keyword arguments:
    -         - message = define a custom message to be used in the raised exception
    -         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
    -         
    -        Example::
    -            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
    -            year_int = integer.copy()
    -            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
    -            date_str = year_int + '/' + integer + '/' + integer
    -
    -            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
    -        """
    -        msg = kwargs.get("message", "failed user-defined condition")
    -        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
    -        for fn in fns:
    -            def pa(s,l,t):
    -                if not bool(_trim_arity(fn)(s,l,t)):
    -                    raise exc_type(s,l,msg)
    -            self.parseAction.append(pa)
    -        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
    -        return self
    -
    -    def setFailAction( self, fn ):
    -        """Define action to perform if parsing fails at this expression.
    -           Fail acton fn is a callable function that takes the arguments
    -           C{fn(s,loc,expr,err)} where:
    -            - s = string being parsed
    -            - loc = location where expression match was attempted and failed
    -            - expr = the parse expression that failed
    -            - err = the exception thrown
    -           The function returns no value.  It may throw C{L{ParseFatalException}}
    -           if it is desired to stop parsing immediately."""
    -        self.failAction = fn
    -        return self
    -
    -    def _skipIgnorables( self, instring, loc ):
    -        exprsFound = True
    -        while exprsFound:
    -            exprsFound = False
    -            for e in self.ignoreExprs:
    -                try:
    -                    while 1:
    -                        loc,dummy = e._parse( instring, loc )
    -                        exprsFound = True
    -                except ParseException:
    -                    pass
    -        return loc
    -
    -    def preParse( self, instring, loc ):
    -        if self.ignoreExprs:
    -            loc = self._skipIgnorables( instring, loc )
    -
    -        if self.skipWhitespace:
    -            wt = self.whiteChars
    -            instrlen = len(instring)
    -            while loc < instrlen and instring[loc] in wt:
    -                loc += 1
    -
    -        return loc
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        return loc, []
    -
    -    def postParse( self, instring, loc, tokenlist ):
    -        return tokenlist
    -
    -    #~ @profile
    -    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
    -        debugging = ( self.debug ) #and doActions )
    -
    -        if debugging or self.failAction:
    -            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
    -            if (self.debugActions[0] ):
    -                self.debugActions[0]( instring, loc, self )
    -            if callPreParse and self.callPreparse:
    -                preloc = self.preParse( instring, loc )
    -            else:
    -                preloc = loc
    -            tokensStart = preloc
    -            try:
    -                try:
    -                    loc,tokens = self.parseImpl( instring, preloc, doActions )
    -                except IndexError:
    -                    raise ParseException( instring, len(instring), self.errmsg, self )
    -            except ParseBaseException as err:
    -                #~ print ("Exception raised:", err)
    -                if self.debugActions[2]:
    -                    self.debugActions[2]( instring, tokensStart, self, err )
    -                if self.failAction:
    -                    self.failAction( instring, tokensStart, self, err )
    -                raise
    -        else:
    -            if callPreParse and self.callPreparse:
    -                preloc = self.preParse( instring, loc )
    -            else:
    -                preloc = loc
    -            tokensStart = preloc
    -            if self.mayIndexError or preloc >= len(instring):
    -                try:
    -                    loc,tokens = self.parseImpl( instring, preloc, doActions )
    -                except IndexError:
    -                    raise ParseException( instring, len(instring), self.errmsg, self )
    -            else:
    -                loc,tokens = self.parseImpl( instring, preloc, doActions )
    -
    -        tokens = self.postParse( instring, loc, tokens )
    -
    -        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
    -        if self.parseAction and (doActions or self.callDuringTry):
    -            if debugging:
    -                try:
    -                    for fn in self.parseAction:
    -                        tokens = fn( instring, tokensStart, retTokens )
    -                        if tokens is not None:
    -                            retTokens = ParseResults( tokens,
    -                                                      self.resultsName,
    -                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
    -                                                      modal=self.modalResults )
    -                except ParseBaseException as err:
    -                    #~ print "Exception raised in user parse action:", err
    -                    if (self.debugActions[2] ):
    -                        self.debugActions[2]( instring, tokensStart, self, err )
    -                    raise
    -            else:
    -                for fn in self.parseAction:
    -                    tokens = fn( instring, tokensStart, retTokens )
    -                    if tokens is not None:
    -                        retTokens = ParseResults( tokens,
    -                                                  self.resultsName,
    -                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
    -                                                  modal=self.modalResults )
    -        if debugging:
    -            #~ print ("Matched",self,"->",retTokens.asList())
    -            if (self.debugActions[1] ):
    -                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
    -
    -        return loc, retTokens
    -
    -    def tryParse( self, instring, loc ):
    -        try:
    -            return self._parse( instring, loc, doActions=False )[0]
    -        except ParseFatalException:
    -            raise ParseException( instring, loc, self.errmsg, self)
    -    
    -    def canParseNext(self, instring, loc):
    -        try:
    -            self.tryParse(instring, loc)
    -        except (ParseException, IndexError):
    -            return False
    -        else:
    -            return True
    -
    -    class _UnboundedCache(object):
    -        def __init__(self):
    -            cache = {}
    -            self.not_in_cache = not_in_cache = object()
    -
    -            def get(self, key):
    -                return cache.get(key, not_in_cache)
    -
    -            def set(self, key, value):
    -                cache[key] = value
    -
    -            def clear(self):
    -                cache.clear()
    -                
    -            def cache_len(self):
    -                return len(cache)
    -
    -            self.get = types.MethodType(get, self)
    -            self.set = types.MethodType(set, self)
    -            self.clear = types.MethodType(clear, self)
    -            self.__len__ = types.MethodType(cache_len, self)
    -
    -    if _OrderedDict is not None:
    -        class _FifoCache(object):
    -            def __init__(self, size):
    -                self.not_in_cache = not_in_cache = object()
    -
    -                cache = _OrderedDict()
    -
    -                def get(self, key):
    -                    return cache.get(key, not_in_cache)
    -
    -                def set(self, key, value):
    -                    cache[key] = value
    -                    while len(cache) > size:
    -                        try:
    -                            cache.popitem(False)
    -                        except KeyError:
    -                            pass
    -
    -                def clear(self):
    -                    cache.clear()
    -
    -                def cache_len(self):
    -                    return len(cache)
    -
    -                self.get = types.MethodType(get, self)
    -                self.set = types.MethodType(set, self)
    -                self.clear = types.MethodType(clear, self)
    -                self.__len__ = types.MethodType(cache_len, self)
    -
    -    else:
    -        class _FifoCache(object):
    -            def __init__(self, size):
    -                self.not_in_cache = not_in_cache = object()
    -
    -                cache = {}
    -                key_fifo = collections.deque([], size)
    -
    -                def get(self, key):
    -                    return cache.get(key, not_in_cache)
    -
    -                def set(self, key, value):
    -                    cache[key] = value
    -                    while len(key_fifo) > size:
    -                        cache.pop(key_fifo.popleft(), None)
    -                    key_fifo.append(key)
    -
    -                def clear(self):
    -                    cache.clear()
    -                    key_fifo.clear()
    -
    -                def cache_len(self):
    -                    return len(cache)
    -
    -                self.get = types.MethodType(get, self)
    -                self.set = types.MethodType(set, self)
    -                self.clear = types.MethodType(clear, self)
    -                self.__len__ = types.MethodType(cache_len, self)
    -
    -    # argument cache for optimizing repeated calls when backtracking through recursive expressions
    -    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
    -    packrat_cache_lock = RLock()
    -    packrat_cache_stats = [0, 0]
    -
    -    # this method gets repeatedly called during backtracking with the same arguments -
    -    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
    -    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
    -        HIT, MISS = 0, 1
    -        lookup = (self, instring, loc, callPreParse, doActions)
    -        with ParserElement.packrat_cache_lock:
    -            cache = ParserElement.packrat_cache
    -            value = cache.get(lookup)
    -            if value is cache.not_in_cache:
    -                ParserElement.packrat_cache_stats[MISS] += 1
    -                try:
    -                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
    -                except ParseBaseException as pe:
    -                    # cache a copy of the exception, without the traceback
    -                    cache.set(lookup, pe.__class__(*pe.args))
    -                    raise
    -                else:
    -                    cache.set(lookup, (value[0], value[1].copy()))
    -                    return value
    -            else:
    -                ParserElement.packrat_cache_stats[HIT] += 1
    -                if isinstance(value, Exception):
    -                    raise value
    -                return (value[0], value[1].copy())
    -
    -    _parse = _parseNoCache
    -
    -    @staticmethod
    -    def resetCache():
    -        ParserElement.packrat_cache.clear()
    -        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
    -
    -    _packratEnabled = False
    -    @staticmethod
    -    def enablePackrat(cache_size_limit=128):
    -        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
    -           Repeated parse attempts at the same string location (which happens
    -           often in many complex grammars) can immediately return a cached value,
    -           instead of re-executing parsing/validating code.  Memoizing is done of
    -           both valid results and parsing exceptions.
    -           
    -           Parameters:
    -            - cache_size_limit - (default=C{128}) - if an integer value is provided
    -              will limit the size of the packrat cache; if None is passed, then
    -              the cache size will be unbounded; if 0 is passed, the cache will
    -              be effectively disabled.
    -            
    -           This speedup may break existing programs that use parse actions that
    -           have side-effects.  For this reason, packrat parsing is disabled when
    -           you first import pyparsing.  To activate the packrat feature, your
    -           program must call the class method C{ParserElement.enablePackrat()}.  If
    -           your program uses C{psyco} to "compile as you go", you must call
    -           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
    -           Python will crash.  For best results, call C{enablePackrat()} immediately
    -           after importing pyparsing.
    -           
    -           Example::
    -               import pyparsing
    -               pyparsing.ParserElement.enablePackrat()
    -        """
    -        if not ParserElement._packratEnabled:
    -            ParserElement._packratEnabled = True
    -            if cache_size_limit is None:
    -                ParserElement.packrat_cache = ParserElement._UnboundedCache()
    -            else:
    -                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
    -            ParserElement._parse = ParserElement._parseCache
    -
    -    def parseString( self, instring, parseAll=False ):
    -        """
    -        Execute the parse expression with the given string.
    -        This is the main interface to the client code, once the complete
    -        expression has been built.
    -
    -        If you want the grammar to require that the entire input string be
    -        successfully parsed, then set C{parseAll} to True (equivalent to ending
    -        the grammar with C{L{StringEnd()}}).
    -
    -        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
    -        in order to report proper column numbers in parse actions.
    -        If the input string contains tabs and
    -        the grammar uses parse actions that use the C{loc} argument to index into the
    -        string being parsed, you can ensure you have a consistent view of the input
    -        string by:
    -         - calling C{parseWithTabs} on your grammar before calling C{parseString}
    -           (see L{I{parseWithTabs}})
    -         - define your parse action using the full C{(s,loc,toks)} signature, and
    -           reference the input string using the parse action's C{s} argument
    -         - explictly expand the tabs in your input string before calling
    -           C{parseString}
    -        
    -        Example::
    -            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
    -            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
    -        """
    -        ParserElement.resetCache()
    -        if not self.streamlined:
    -            self.streamline()
    -            #~ self.saveAsList = True
    -        for e in self.ignoreExprs:
    -            e.streamline()
    -        if not self.keepTabs:
    -            instring = instring.expandtabs()
    -        try:
    -            loc, tokens = self._parse( instring, 0 )
    -            if parseAll:
    -                loc = self.preParse( instring, loc )
    -                se = Empty() + StringEnd()
    -                se._parse( instring, loc )
    -        except ParseBaseException as exc:
    -            if ParserElement.verbose_stacktrace:
    -                raise
    -            else:
    -                # catch and re-raise exception from here, clears out pyparsing internal stack trace
    -                raise exc
    -        else:
    -            return tokens
    -
    -    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
    -        """
    -        Scan the input string for expression matches.  Each match will return the
    -        matching tokens, start location, and end location.  May be called with optional
    -        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
    -        C{overlap} is specified, then overlapping matches will be reported.
    -
    -        Note that the start and end locations are reported relative to the string
    -        being parsed.  See L{I{parseString}} for more information on parsing
    -        strings with embedded tabs.
    -
    -        Example::
    -            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
    -            print(source)
    -            for tokens,start,end in Word(alphas).scanString(source):
    -                print(' '*start + '^'*(end-start))
    -                print(' '*start + tokens[0])
    -        
    -        prints::
    -        
    -            sldjf123lsdjjkf345sldkjf879lkjsfd987
    -            ^^^^^
    -            sldjf
    -                    ^^^^^^^
    -                    lsdjjkf
    -                              ^^^^^^
    -                              sldkjf
    -                                       ^^^^^^
    -                                       lkjsfd
    -        """
    -        if not self.streamlined:
    -            self.streamline()
    -        for e in self.ignoreExprs:
    -            e.streamline()
    -
    -        if not self.keepTabs:
    -            instring = _ustr(instring).expandtabs()
    -        instrlen = len(instring)
    -        loc = 0
    -        preparseFn = self.preParse
    -        parseFn = self._parse
    -        ParserElement.resetCache()
    -        matches = 0
    -        try:
    -            while loc <= instrlen and matches < maxMatches:
    -                try:
    -                    preloc = preparseFn( instring, loc )
    -                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
    -                except ParseException:
    -                    loc = preloc+1
    -                else:
    -                    if nextLoc > loc:
    -                        matches += 1
    -                        yield tokens, preloc, nextLoc
    -                        if overlap:
    -                            nextloc = preparseFn( instring, loc )
    -                            if nextloc > loc:
    -                                loc = nextLoc
    -                            else:
    -                                loc += 1
    -                        else:
    -                            loc = nextLoc
    -                    else:
    -                        loc = preloc+1
    -        except ParseBaseException as exc:
    -            if ParserElement.verbose_stacktrace:
    -                raise
    -            else:
    -                # catch and re-raise exception from here, clears out pyparsing internal stack trace
    -                raise exc
    -
    -    def transformString( self, instring ):
    -        """
    -        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
    -        be returned from a parse action.  To use C{transformString}, define a grammar and
    -        attach a parse action to it that modifies the returned token list.
    -        Invoking C{transformString()} on a target string will then scan for matches,
    -        and replace the matched text patterns according to the logic in the parse
    -        action.  C{transformString()} returns the resulting transformed string.
    -        
    -        Example::
    -            wd = Word(alphas)
    -            wd.setParseAction(lambda toks: toks[0].title())
    -            
    -            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
    -        Prints::
    -            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
    -        """
    -        out = []
    -        lastE = 0
    -        # force preservation of s, to minimize unwanted transformation of string, and to
    -        # keep string locs straight between transformString and scanString
    -        self.keepTabs = True
    -        try:
    -            for t,s,e in self.scanString( instring ):
    -                out.append( instring[lastE:s] )
    -                if t:
    -                    if isinstance(t,ParseResults):
    -                        out += t.asList()
    -                    elif isinstance(t,list):
    -                        out += t
    -                    else:
    -                        out.append(t)
    -                lastE = e
    -            out.append(instring[lastE:])
    -            out = [o for o in out if o]
    -            return "".join(map(_ustr,_flatten(out)))
    -        except ParseBaseException as exc:
    -            if ParserElement.verbose_stacktrace:
    -                raise
    -            else:
    -                # catch and re-raise exception from here, clears out pyparsing internal stack trace
    -                raise exc
    -
    -    def searchString( self, instring, maxMatches=_MAX_INT ):
    -        """
    -        Another extension to C{L{scanString}}, simplifying the access to the tokens found
    -        to match the given parse expression.  May be called with optional
    -        C{maxMatches} argument, to clip searching after 'n' matches are found.
    -        
    -        Example::
    -            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
    -            cap_word = Word(alphas.upper(), alphas.lower())
    -            
    -            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
    -
    -            # the sum() builtin can be used to merge results into a single ParseResults object
    -            print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")))
    -        prints::
    -            [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']]
    -            ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity']
    -        """
    -        try:
    -            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
    -        except ParseBaseException as exc:
    -            if ParserElement.verbose_stacktrace:
    -                raise
    -            else:
    -                # catch and re-raise exception from here, clears out pyparsing internal stack trace
    -                raise exc
    -
    -    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
    -        """
    -        Generator method to split a string using the given expression as a separator.
    -        May be called with optional C{maxsplit} argument, to limit the number of splits;
    -        and the optional C{includeSeparators} argument (default=C{False}), if the separating
    -        matching text should be included in the split results.
    -        
    -        Example::        
    -            punc = oneOf(list(".,;:/-!?"))
    -            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
    -        prints::
    -            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
    -        """
    -        splits = 0
    -        last = 0
    -        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
    -            yield instring[last:s]
    -            if includeSeparators:
    -                yield t[0]
    -            last = e
    -        yield instring[last:]
    -
    -    def __add__(self, other ):
    -        """
    -        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
    -        converts them to L{Literal}s by default.
    -        
    -        Example::
    -            greet = Word(alphas) + "," + Word(alphas) + "!"
    -            hello = "Hello, World!"
    -            print (hello, "->", greet.parseString(hello))
    -        Prints::
    -            Hello, World! -> ['Hello', ',', 'World', '!']
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return And( [ self, other ] )
    -
    -    def __radd__(self, other ):
    -        """
    -        Implementation of + operator when left operand is not a C{L{ParserElement}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return other + self
    -
    -    def __sub__(self, other):
    -        """
    -        Implementation of - operator, returns C{L{And}} with error stop
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return self + And._ErrorStop() + other
    -
    -    def __rsub__(self, other ):
    -        """
    -        Implementation of - operator when left operand is not a C{L{ParserElement}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return other - self
    -
    -    def __mul__(self,other):
    -        """
    -        Implementation of * operator, allows use of C{expr * 3} in place of
    -        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
    -        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
    -        may also include C{None} as in:
    -         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
    -              to C{expr*n + L{ZeroOrMore}(expr)}
    -              (read as "at least n instances of C{expr}")
    -         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
    -              (read as "0 to n instances of C{expr}")
    -         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
    -         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
    -
    -        Note that C{expr*(None,n)} does not raise an exception if
    -        more than n exprs exist in the input stream; that is,
    -        C{expr*(None,n)} does not enforce a maximum number of expr
    -        occurrences.  If this behavior is desired, then write
    -        C{expr*(None,n) + ~expr}
    -        """
    -        if isinstance(other,int):
    -            minElements, optElements = other,0
    -        elif isinstance(other,tuple):
    -            other = (other + (None, None))[:2]
    -            if other[0] is None:
    -                other = (0, other[1])
    -            if isinstance(other[0],int) and other[1] is None:
    -                if other[0] == 0:
    -                    return ZeroOrMore(self)
    -                if other[0] == 1:
    -                    return OneOrMore(self)
    -                else:
    -                    return self*other[0] + ZeroOrMore(self)
    -            elif isinstance(other[0],int) and isinstance(other[1],int):
    -                minElements, optElements = other
    -                optElements -= minElements
    -            else:
    -                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
    -        else:
    -            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
    -
    -        if minElements < 0:
    -            raise ValueError("cannot multiply ParserElement by negative value")
    -        if optElements < 0:
    -            raise ValueError("second tuple value must be greater or equal to first tuple value")
    -        if minElements == optElements == 0:
    -            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
    -
    -        if (optElements):
    -            def makeOptionalList(n):
    -                if n>1:
    -                    return Optional(self + makeOptionalList(n-1))
    -                else:
    -                    return Optional(self)
    -            if minElements:
    -                if minElements == 1:
    -                    ret = self + makeOptionalList(optElements)
    -                else:
    -                    ret = And([self]*minElements) + makeOptionalList(optElements)
    -            else:
    -                ret = makeOptionalList(optElements)
    -        else:
    -            if minElements == 1:
    -                ret = self
    -            else:
    -                ret = And([self]*minElements)
    -        return ret
    -
    -    def __rmul__(self, other):
    -        return self.__mul__(other)
    -
    -    def __or__(self, other ):
    -        """
    -        Implementation of | operator - returns C{L{MatchFirst}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return MatchFirst( [ self, other ] )
    -
    -    def __ror__(self, other ):
    -        """
    -        Implementation of | operator when left operand is not a C{L{ParserElement}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return other | self
    -
    -    def __xor__(self, other ):
    -        """
    -        Implementation of ^ operator - returns C{L{Or}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return Or( [ self, other ] )
    -
    -    def __rxor__(self, other ):
    -        """
    -        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return other ^ self
    -
    -    def __and__(self, other ):
    -        """
    -        Implementation of & operator - returns C{L{Each}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return Each( [ self, other ] )
    -
    -    def __rand__(self, other ):
    -        """
    -        Implementation of & operator when left operand is not a C{L{ParserElement}}
    -        """
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        if not isinstance( other, ParserElement ):
    -            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
    -                    SyntaxWarning, stacklevel=2)
    -            return None
    -        return other & self
    -
    -    def __invert__( self ):
    -        """
    -        Implementation of ~ operator - returns C{L{NotAny}}
    -        """
    -        return NotAny( self )
    -
    -    def __call__(self, name=None):
    -        """
    -        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
    -        
    -        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
    -        passed as C{True}.
    -           
    -        If C{name} is omitted, same as calling C{L{copy}}.
    -
    -        Example::
    -            # these are equivalent
    -            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
    -            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
    -        """
    -        if name is not None:
    -            return self.setResultsName(name)
    -        else:
    -            return self.copy()
    -
    -    def suppress( self ):
    -        """
    -        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
    -        cluttering up returned output.
    -        """
    -        return Suppress( self )
    -
    -    def leaveWhitespace( self ):
    -        """
    -        Disables the skipping of whitespace before matching the characters in the
    -        C{ParserElement}'s defined pattern.  This is normally only used internally by
    -        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
    -        """
    -        self.skipWhitespace = False
    -        return self
    -
    -    def setWhitespaceChars( self, chars ):
    -        """
    -        Overrides the default whitespace chars
    -        """
    -        self.skipWhitespace = True
    -        self.whiteChars = chars
    -        self.copyDefaultWhiteChars = False
    -        return self
    -
    -    def parseWithTabs( self ):
    -        """
    -        Overrides default behavior to expand C{}s to spaces before parsing the input string.
    -        Must be called before C{parseString} when the input grammar contains elements that
    -        match C{} characters.
    -        """
    -        self.keepTabs = True
    -        return self
    -
    -    def ignore( self, other ):
    -        """
    -        Define expression to be ignored (e.g., comments) while doing pattern
    -        matching; may be called repeatedly, to define multiple comment or other
    -        ignorable patterns.
    -        
    -        Example::
    -            patt = OneOrMore(Word(alphas))
    -            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
    -            
    -            patt.ignore(cStyleComment)
    -            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
    -        """
    -        if isinstance(other, basestring):
    -            other = Suppress(other)
    -
    -        if isinstance( other, Suppress ):
    -            if other not in self.ignoreExprs:
    -                self.ignoreExprs.append(other)
    -        else:
    -            self.ignoreExprs.append( Suppress( other.copy() ) )
    -        return self
    -
    -    def setDebugActions( self, startAction, successAction, exceptionAction ):
    -        """
    -        Enable display of debugging messages while doing pattern matching.
    -        """
    -        self.debugActions = (startAction or _defaultStartDebugAction,
    -                             successAction or _defaultSuccessDebugAction,
    -                             exceptionAction or _defaultExceptionDebugAction)
    -        self.debug = True
    -        return self
    -
    -    def setDebug( self, flag=True ):
    -        """
    -        Enable display of debugging messages while doing pattern matching.
    -        Set C{flag} to True to enable, False to disable.
    -
    -        Example::
    -            wd = Word(alphas).setName("alphaword")
    -            integer = Word(nums).setName("numword")
    -            term = wd | integer
    -            
    -            # turn on debugging for wd
    -            wd.setDebug()
    -
    -            OneOrMore(term).parseString("abc 123 xyz 890")
    -        
    -        prints::
    -            Match alphaword at loc 0(1,1)
    -            Matched alphaword -> ['abc']
    -            Match alphaword at loc 3(1,4)
    -            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
    -            Match alphaword at loc 7(1,8)
    -            Matched alphaword -> ['xyz']
    -            Match alphaword at loc 11(1,12)
    -            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
    -            Match alphaword at loc 15(1,16)
    -            Exception raised:Expected alphaword (at char 15), (line:1, col:16)
    -
    -        The output shown is that produced by the default debug actions - custom debug actions can be
    -        specified using L{setDebugActions}. Prior to attempting
    -        to match the C{wd} expression, the debugging message C{"Match  at loc (,)"}
    -        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
    -        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
    -        which makes debugging and exception messages easier to understand - for instance, the default
    -        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
    -        """
    -        if flag:
    -            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
    -        else:
    -            self.debug = False
    -        return self
    -
    -    def __str__( self ):
    -        return self.name
    -
    -    def __repr__( self ):
    -        return _ustr(self)
    -
    -    def streamline( self ):
    -        self.streamlined = True
    -        self.strRepr = None
    -        return self
    -
    -    def checkRecursion( self, parseElementList ):
    -        pass
    -
    -    def validate( self, validateTrace=[] ):
    -        """
    -        Check defined expressions for valid structure, check for infinite recursive definitions.
    -        """
    -        self.checkRecursion( [] )
    -
    -    def parseFile( self, file_or_filename, parseAll=False ):
    -        """
    -        Execute the parse expression on the given file or filename.
    -        If a filename is specified (instead of a file object),
    -        the entire file is opened, read, and closed before parsing.
    -        """
    -        try:
    -            file_contents = file_or_filename.read()
    -        except AttributeError:
    -            with open(file_or_filename, "r") as f:
    -                file_contents = f.read()
    -        try:
    -            return self.parseString(file_contents, parseAll)
    -        except ParseBaseException as exc:
    -            if ParserElement.verbose_stacktrace:
    -                raise
    -            else:
    -                # catch and re-raise exception from here, clears out pyparsing internal stack trace
    -                raise exc
    -
    -    def __eq__(self,other):
    -        if isinstance(other, ParserElement):
    -            return self is other or vars(self) == vars(other)
    -        elif isinstance(other, basestring):
    -            return self.matches(other)
    -        else:
    -            return super(ParserElement,self)==other
    -
    -    def __ne__(self,other):
    -        return not (self == other)
    -
    -    def __hash__(self):
    -        return hash(id(self))
    -
    -    def __req__(self,other):
    -        return self == other
    -
    -    def __rne__(self,other):
    -        return not (self == other)
    -
    -    def matches(self, testString, parseAll=True):
    -        """
    -        Method for quick testing of a parser against a test string. Good for simple 
    -        inline microtests of sub expressions while building up larger parser.
    -           
    -        Parameters:
    -         - testString - to test against this expression for a match
    -         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
    -            
    -        Example::
    -            expr = Word(nums)
    -            assert expr.matches("100")
    -        """
    -        try:
    -            self.parseString(_ustr(testString), parseAll=parseAll)
    -            return True
    -        except ParseBaseException:
    -            return False
    -                
    -    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
    -        """
    -        Execute the parse expression on a series of test strings, showing each
    -        test, the parsed results or where the parse failed. Quick and easy way to
    -        run a parse expression against a list of sample strings.
    -           
    -        Parameters:
    -         - tests - a list of separate test strings, or a multiline string of test strings
    -         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
    -         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
    -              string; pass None to disable comment filtering
    -         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
    -              if False, only dump nested list
    -         - printResults - (default=C{True}) prints test output to stdout
    -         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
    -
    -        Returns: a (success, results) tuple, where success indicates that all tests succeeded
    -        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
    -        test's output
    -        
    -        Example::
    -            number_expr = pyparsing_common.number.copy()
    -
    -            result = number_expr.runTests('''
    -                # unsigned integer
    -                100
    -                # negative integer
    -                -100
    -                # float with scientific notation
    -                6.02e23
    -                # integer with scientific notation
    -                1e-12
    -                ''')
    -            print("Success" if result[0] else "Failed!")
    -
    -            result = number_expr.runTests('''
    -                # stray character
    -                100Z
    -                # missing leading digit before '.'
    -                -.100
    -                # too many '.'
    -                3.14.159
    -                ''', failureTests=True)
    -            print("Success" if result[0] else "Failed!")
    -        prints::
    -            # unsigned integer
    -            100
    -            [100]
    -
    -            # negative integer
    -            -100
    -            [-100]
    -
    -            # float with scientific notation
    -            6.02e23
    -            [6.02e+23]
    -
    -            # integer with scientific notation
    -            1e-12
    -            [1e-12]
    -
    -            Success
    -            
    -            # stray character
    -            100Z
    -               ^
    -            FAIL: Expected end of text (at char 3), (line:1, col:4)
    -
    -            # missing leading digit before '.'
    -            -.100
    -            ^
    -            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
    -
    -            # too many '.'
    -            3.14.159
    -                ^
    -            FAIL: Expected end of text (at char 4), (line:1, col:5)
    -
    -            Success
    -
    -        Each test string must be on a single line. If you want to test a string that spans multiple
    -        lines, create a test like this::
    -
    -            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
    -        
    -        (Note that this is a raw string literal, you must include the leading 'r'.)
    -        """
    -        if isinstance(tests, basestring):
    -            tests = list(map(str.strip, tests.rstrip().splitlines()))
    -        if isinstance(comment, basestring):
    -            comment = Literal(comment)
    -        allResults = []
    -        comments = []
    -        success = True
    -        for t in tests:
    -            if comment is not None and comment.matches(t, False) or comments and not t:
    -                comments.append(t)
    -                continue
    -            if not t:
    -                continue
    -            out = ['\n'.join(comments), t]
    -            comments = []
    -            try:
    -                t = t.replace(r'\n','\n')
    -                result = self.parseString(t, parseAll=parseAll)
    -                out.append(result.dump(full=fullDump))
    -                success = success and not failureTests
    -            except ParseBaseException as pe:
    -                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
    -                if '\n' in t:
    -                    out.append(line(pe.loc, t))
    -                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
    -                else:
    -                    out.append(' '*pe.loc + '^' + fatal)
    -                out.append("FAIL: " + str(pe))
    -                success = success and failureTests
    -                result = pe
    -            except Exception as exc:
    -                out.append("FAIL-EXCEPTION: " + str(exc))
    -                success = success and failureTests
    -                result = exc
    -
    -            if printResults:
    -                if fullDump:
    -                    out.append('')
    -                print('\n'.join(out))
    -
    -            allResults.append((t, result))
    -        
    -        return success, allResults
    -
    -        
    -class Token(ParserElement):
    -    """
    -    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
    -    """
    -    def __init__( self ):
    -        super(Token,self).__init__( savelist=False )
    -
    -
    -class Empty(Token):
    -    """
    -    An empty token, will always match.
    -    """
    -    def __init__( self ):
    -        super(Empty,self).__init__()
    -        self.name = "Empty"
    -        self.mayReturnEmpty = True
    -        self.mayIndexError = False
    -
    -
    -class NoMatch(Token):
    -    """
    -    A token that will never match.
    -    """
    -    def __init__( self ):
    -        super(NoMatch,self).__init__()
    -        self.name = "NoMatch"
    -        self.mayReturnEmpty = True
    -        self.mayIndexError = False
    -        self.errmsg = "Unmatchable token"
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -
    -class Literal(Token):
    -    """
    -    Token to exactly match a specified string.
    -    
    -    Example::
    -        Literal('blah').parseString('blah')  # -> ['blah']
    -        Literal('blah').parseString('blahfooblah')  # -> ['blah']
    -        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
    -    
    -    For case-insensitive matching, use L{CaselessLiteral}.
    -    
    -    For keyword matching (force word break before and after the matched string),
    -    use L{Keyword} or L{CaselessKeyword}.
    -    """
    -    def __init__( self, matchString ):
    -        super(Literal,self).__init__()
    -        self.match = matchString
    -        self.matchLen = len(matchString)
    -        try:
    -            self.firstMatchChar = matchString[0]
    -        except IndexError:
    -            warnings.warn("null string passed to Literal; use Empty() instead",
    -                            SyntaxWarning, stacklevel=2)
    -            self.__class__ = Empty
    -        self.name = '"%s"' % _ustr(self.match)
    -        self.errmsg = "Expected " + self.name
    -        self.mayReturnEmpty = False
    -        self.mayIndexError = False
    -
    -    # Performance tuning: this routine gets called a *lot*
    -    # if this is a single character match string  and the first character matches,
    -    # short-circuit as quickly as possible, and avoid calling startswith
    -    #~ @profile
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if (instring[loc] == self.firstMatchChar and
    -            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
    -            return loc+self.matchLen, self.match
    -        raise ParseException(instring, loc, self.errmsg, self)
    -_L = Literal
    -ParserElement._literalStringClass = Literal
    -
    -class Keyword(Token):
    -    """
    -    Token to exactly match a specified string as a keyword, that is, it must be
    -    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
    -     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
    -     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
    -    Accepts two optional constructor arguments in addition to the keyword string:
    -     - C{identChars} is a string of characters that would be valid identifier characters,
    -          defaulting to all alphanumerics + "_" and "$"
    -     - C{caseless} allows case-insensitive matching, default is C{False}.
    -       
    -    Example::
    -        Keyword("start").parseString("start")  # -> ['start']
    -        Keyword("start").parseString("starting")  # -> Exception
    -
    -    For case-insensitive matching, use L{CaselessKeyword}.
    -    """
    -    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
    -
    -    def __init__( self, matchString, identChars=None, caseless=False ):
    -        super(Keyword,self).__init__()
    -        if identChars is None:
    -            identChars = Keyword.DEFAULT_KEYWORD_CHARS
    -        self.match = matchString
    -        self.matchLen = len(matchString)
    -        try:
    -            self.firstMatchChar = matchString[0]
    -        except IndexError:
    -            warnings.warn("null string passed to Keyword; use Empty() instead",
    -                            SyntaxWarning, stacklevel=2)
    -        self.name = '"%s"' % self.match
    -        self.errmsg = "Expected " + self.name
    -        self.mayReturnEmpty = False
    -        self.mayIndexError = False
    -        self.caseless = caseless
    -        if caseless:
    -            self.caselessmatch = matchString.upper()
    -            identChars = identChars.upper()
    -        self.identChars = set(identChars)
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if self.caseless:
    -            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
    -                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
    -                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
    -                return loc+self.matchLen, self.match
    -        else:
    -            if (instring[loc] == self.firstMatchChar and
    -                (self.matchLen==1 or instring.startswith(self.match,loc)) and
    -                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
    -                (loc == 0 or instring[loc-1] not in self.identChars) ):
    -                return loc+self.matchLen, self.match
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -    def copy(self):
    -        c = super(Keyword,self).copy()
    -        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
    -        return c
    -
    -    @staticmethod
    -    def setDefaultKeywordChars( chars ):
    -        """Overrides the default Keyword chars
    -        """
    -        Keyword.DEFAULT_KEYWORD_CHARS = chars
    -
    -class CaselessLiteral(Literal):
    -    """
    -    Token to match a specified string, ignoring case of letters.
    -    Note: the matched results will always be in the case of the given
    -    match string, NOT the case of the input text.
    -
    -    Example::
    -        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
    -        
    -    (Contrast with example for L{CaselessKeyword}.)
    -    """
    -    def __init__( self, matchString ):
    -        super(CaselessLiteral,self).__init__( matchString.upper() )
    -        # Preserve the defining literal.
    -        self.returnString = matchString
    -        self.name = "'%s'" % self.returnString
    -        self.errmsg = "Expected " + self.name
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if instring[ loc:loc+self.matchLen ].upper() == self.match:
    -            return loc+self.matchLen, self.returnString
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -class CaselessKeyword(Keyword):
    -    """
    -    Caseless version of L{Keyword}.
    -
    -    Example::
    -        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
    -        
    -    (Contrast with example for L{CaselessLiteral}.)
    -    """
    -    def __init__( self, matchString, identChars=None ):
    -        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
    -             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
    -            return loc+self.matchLen, self.match
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -class CloseMatch(Token):
    -    """
    -    A variation on L{Literal} which matches "close" matches, that is, 
    -    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
    -     - C{match_string} - string to be matched
    -     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
    -    
    -    The results from a successful parse will contain the matched text from the input string and the following named results:
    -     - C{mismatches} - a list of the positions within the match_string where mismatches were found
    -     - C{original} - the original match_string used to compare against the input string
    -    
    -    If C{mismatches} is an empty list, then the match was an exact match.
    -    
    -    Example::
    -        patt = CloseMatch("ATCATCGAATGGA")
    -        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
    -        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
    -
    -        # exact match
    -        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
    -
    -        # close match allowing up to 2 mismatches
    -        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
    -        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
    -    """
    -    def __init__(self, match_string, maxMismatches=1):
    -        super(CloseMatch,self).__init__()
    -        self.name = match_string
    -        self.match_string = match_string
    -        self.maxMismatches = maxMismatches
    -        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
    -        self.mayIndexError = False
    -        self.mayReturnEmpty = False
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        start = loc
    -        instrlen = len(instring)
    -        maxloc = start + len(self.match_string)
    -
    -        if maxloc <= instrlen:
    -            match_string = self.match_string
    -            match_stringloc = 0
    -            mismatches = []
    -            maxMismatches = self.maxMismatches
    -
    -            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
    -                src,mat = s_m
    -                if src != mat:
    -                    mismatches.append(match_stringloc)
    -                    if len(mismatches) > maxMismatches:
    -                        break
    -            else:
    -                loc = match_stringloc + 1
    -                results = ParseResults([instring[start:loc]])
    -                results['original'] = self.match_string
    -                results['mismatches'] = mismatches
    -                return loc, results
    -
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -
    -class Word(Token):
    -    """
    -    Token for matching words composed of allowed character sets.
    -    Defined with string containing all allowed initial characters,
    -    an optional string containing allowed body characters (if omitted,
    -    defaults to the initial character set), and an optional minimum,
    -    maximum, and/or exact length.  The default value for C{min} is 1 (a
    -    minimum value < 1 is not valid); the default values for C{max} and C{exact}
    -    are 0, meaning no maximum or exact length restriction. An optional
    -    C{excludeChars} parameter can list characters that might be found in 
    -    the input C{bodyChars} string; useful to define a word of all printables
    -    except for one or two characters, for instance.
    -    
    -    L{srange} is useful for defining custom character set strings for defining 
    -    C{Word} expressions, using range notation from regular expression character sets.
    -    
    -    A common mistake is to use C{Word} to match a specific literal string, as in 
    -    C{Word("Address")}. Remember that C{Word} uses the string argument to define
    -    I{sets} of matchable characters. This expression would match "Add", "AAA",
    -    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
    -    To match an exact literal string, use L{Literal} or L{Keyword}.
    -
    -    pyparsing includes helper strings for building Words:
    -     - L{alphas}
    -     - L{nums}
    -     - L{alphanums}
    -     - L{hexnums}
    -     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
    -     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
    -     - L{printables} (any non-whitespace character)
    -
    -    Example::
    -        # a word composed of digits
    -        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
    -        
    -        # a word with a leading capital, and zero or more lowercase
    -        capital_word = Word(alphas.upper(), alphas.lower())
    -
    -        # hostnames are alphanumeric, with leading alpha, and '-'
    -        hostname = Word(alphas, alphanums+'-')
    -        
    -        # roman numeral (not a strict parser, accepts invalid mix of characters)
    -        roman = Word("IVXLCDM")
    -        
    -        # any string of non-whitespace characters, except for ','
    -        csv_value = Word(printables, excludeChars=",")
    -    """
    -    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
    -        super(Word,self).__init__()
    -        if excludeChars:
    -            initChars = ''.join(c for c in initChars if c not in excludeChars)
    -            if bodyChars:
    -                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
    -        self.initCharsOrig = initChars
    -        self.initChars = set(initChars)
    -        if bodyChars :
    -            self.bodyCharsOrig = bodyChars
    -            self.bodyChars = set(bodyChars)
    -        else:
    -            self.bodyCharsOrig = initChars
    -            self.bodyChars = set(initChars)
    -
    -        self.maxSpecified = max > 0
    -
    -        if min < 1:
    -            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
    -
    -        self.minLen = min
    -
    -        if max > 0:
    -            self.maxLen = max
    -        else:
    -            self.maxLen = _MAX_INT
    -
    -        if exact > 0:
    -            self.maxLen = exact
    -            self.minLen = exact
    -
    -        self.name = _ustr(self)
    -        self.errmsg = "Expected " + self.name
    -        self.mayIndexError = False
    -        self.asKeyword = asKeyword
    -
    -        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
    -            if self.bodyCharsOrig == self.initCharsOrig:
    -                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
    -            elif len(self.initCharsOrig) == 1:
    -                self.reString = "%s[%s]*" % \
    -                                      (re.escape(self.initCharsOrig),
    -                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
    -            else:
    -                self.reString = "[%s][%s]*" % \
    -                                      (_escapeRegexRangeChars(self.initCharsOrig),
    -                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
    -            if self.asKeyword:
    -                self.reString = r"\b"+self.reString+r"\b"
    -            try:
    -                self.re = re.compile( self.reString )
    -            except Exception:
    -                self.re = None
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if self.re:
    -            result = self.re.match(instring,loc)
    -            if not result:
    -                raise ParseException(instring, loc, self.errmsg, self)
    -
    -            loc = result.end()
    -            return loc, result.group()
    -
    -        if not(instring[ loc ] in self.initChars):
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        start = loc
    -        loc += 1
    -        instrlen = len(instring)
    -        bodychars = self.bodyChars
    -        maxloc = start + self.maxLen
    -        maxloc = min( maxloc, instrlen )
    -        while loc < maxloc and instring[loc] in bodychars:
    -            loc += 1
    -
    -        throwException = False
    -        if loc - start < self.minLen:
    -            throwException = True
    -        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
    -            throwException = True
    -        if self.asKeyword:
    -            if (start>0 and instring[start-1] in bodychars) or (loc4:
    -                    return s[:4]+"..."
    -                else:
    -                    return s
    -
    -            if ( self.initCharsOrig != self.bodyCharsOrig ):
    -                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
    -            else:
    -                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
    -
    -        return self.strRepr
    -
    -
    -class Regex(Token):
    -    r"""
    -    Token for matching strings that match a given regular expression.
    -    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
    -    If the given regex contains named groups (defined using C{(?P...)}), these will be preserved as 
    -    named parse results.
    -
    -    Example::
    -        realnum = Regex(r"[+-]?\d+\.\d*")
    -        date = Regex(r'(?P\d{4})-(?P\d\d?)-(?P\d\d?)')
    -        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
    -        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
    -    """
    -    compiledREtype = type(re.compile("[A-Z]"))
    -    def __init__( self, pattern, flags=0):
    -        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
    -        super(Regex,self).__init__()
    -
    -        if isinstance(pattern, basestring):
    -            if not pattern:
    -                warnings.warn("null string passed to Regex; use Empty() instead",
    -                        SyntaxWarning, stacklevel=2)
    -
    -            self.pattern = pattern
    -            self.flags = flags
    -
    -            try:
    -                self.re = re.compile(self.pattern, self.flags)
    -                self.reString = self.pattern
    -            except sre_constants.error:
    -                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
    -                    SyntaxWarning, stacklevel=2)
    -                raise
    -
    -        elif isinstance(pattern, Regex.compiledREtype):
    -            self.re = pattern
    -            self.pattern = \
    -            self.reString = str(pattern)
    -            self.flags = flags
    -            
    -        else:
    -            raise ValueError("Regex may only be constructed with a string or a compiled RE object")
    -
    -        self.name = _ustr(self)
    -        self.errmsg = "Expected " + self.name
    -        self.mayIndexError = False
    -        self.mayReturnEmpty = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        result = self.re.match(instring,loc)
    -        if not result:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        loc = result.end()
    -        d = result.groupdict()
    -        ret = ParseResults(result.group())
    -        if d:
    -            for k in d:
    -                ret[k] = d[k]
    -        return loc,ret
    -
    -    def __str__( self ):
    -        try:
    -            return super(Regex,self).__str__()
    -        except Exception:
    -            pass
    -
    -        if self.strRepr is None:
    -            self.strRepr = "Re:(%s)" % repr(self.pattern)
    -
    -        return self.strRepr
    -
    -
    -class QuotedString(Token):
    -    r"""
    -    Token for matching strings that are delimited by quoting characters.
    -    
    -    Defined with the following parameters:
    -        - quoteChar - string of one or more characters defining the quote delimiting string
    -        - escChar - character to escape quotes, typically backslash (default=C{None})
    -        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
    -        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
    -        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
    -        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
    -        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
    -
    -    Example::
    -        qs = QuotedString('"')
    -        print(qs.searchString('lsjdf "This is the quote" sldjf'))
    -        complex_qs = QuotedString('{{', endQuoteChar='}}')
    -        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
    -        sql_qs = QuotedString('"', escQuote='""')
    -        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
    -    prints::
    -        [['This is the quote']]
    -        [['This is the "quote"']]
    -        [['This is the quote with "embedded" quotes']]
    -    """
    -    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
    -        super(QuotedString,self).__init__()
    -
    -        # remove white space from quote chars - wont work anyway
    -        quoteChar = quoteChar.strip()
    -        if not quoteChar:
    -            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
    -            raise SyntaxError()
    -
    -        if endQuoteChar is None:
    -            endQuoteChar = quoteChar
    -        else:
    -            endQuoteChar = endQuoteChar.strip()
    -            if not endQuoteChar:
    -                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
    -                raise SyntaxError()
    -
    -        self.quoteChar = quoteChar
    -        self.quoteCharLen = len(quoteChar)
    -        self.firstQuoteChar = quoteChar[0]
    -        self.endQuoteChar = endQuoteChar
    -        self.endQuoteCharLen = len(endQuoteChar)
    -        self.escChar = escChar
    -        self.escQuote = escQuote
    -        self.unquoteResults = unquoteResults
    -        self.convertWhitespaceEscapes = convertWhitespaceEscapes
    -
    -        if multiline:
    -            self.flags = re.MULTILINE | re.DOTALL
    -            self.pattern = r'%s(?:[^%s%s]' % \
    -                ( re.escape(self.quoteChar),
    -                  _escapeRegexRangeChars(self.endQuoteChar[0]),
    -                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
    -        else:
    -            self.flags = 0
    -            self.pattern = r'%s(?:[^%s\n\r%s]' % \
    -                ( re.escape(self.quoteChar),
    -                  _escapeRegexRangeChars(self.endQuoteChar[0]),
    -                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
    -        if len(self.endQuoteChar) > 1:
    -            self.pattern += (
    -                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
    -                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
    -                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
    -                )
    -        if escQuote:
    -            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
    -        if escChar:
    -            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
    -            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
    -        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
    -
    -        try:
    -            self.re = re.compile(self.pattern, self.flags)
    -            self.reString = self.pattern
    -        except sre_constants.error:
    -            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
    -                SyntaxWarning, stacklevel=2)
    -            raise
    -
    -        self.name = _ustr(self)
    -        self.errmsg = "Expected " + self.name
    -        self.mayIndexError = False
    -        self.mayReturnEmpty = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
    -        if not result:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        loc = result.end()
    -        ret = result.group()
    -
    -        if self.unquoteResults:
    -
    -            # strip off quotes
    -            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
    -
    -            if isinstance(ret,basestring):
    -                # replace escaped whitespace
    -                if '\\' in ret and self.convertWhitespaceEscapes:
    -                    ws_map = {
    -                        r'\t' : '\t',
    -                        r'\n' : '\n',
    -                        r'\f' : '\f',
    -                        r'\r' : '\r',
    -                    }
    -                    for wslit,wschar in ws_map.items():
    -                        ret = ret.replace(wslit, wschar)
    -
    -                # replace escaped characters
    -                if self.escChar:
    -                    ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret)
    -
    -                # replace escaped quotes
    -                if self.escQuote:
    -                    ret = ret.replace(self.escQuote, self.endQuoteChar)
    -
    -        return loc, ret
    -
    -    def __str__( self ):
    -        try:
    -            return super(QuotedString,self).__str__()
    -        except Exception:
    -            pass
    -
    -        if self.strRepr is None:
    -            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
    -
    -        return self.strRepr
    -
    -
    -class CharsNotIn(Token):
    -    """
    -    Token for matching words composed of characters I{not} in a given set (will
    -    include whitespace in matched characters if not listed in the provided exclusion set - see example).
    -    Defined with string containing all disallowed characters, and an optional
    -    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
    -    minimum value < 1 is not valid); the default values for C{max} and C{exact}
    -    are 0, meaning no maximum or exact length restriction.
    -
    -    Example::
    -        # define a comma-separated-value as anything that is not a ','
    -        csv_value = CharsNotIn(',')
    -        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
    -    prints::
    -        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
    -    """
    -    def __init__( self, notChars, min=1, max=0, exact=0 ):
    -        super(CharsNotIn,self).__init__()
    -        self.skipWhitespace = False
    -        self.notChars = notChars
    -
    -        if min < 1:
    -            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
    -
    -        self.minLen = min
    -
    -        if max > 0:
    -            self.maxLen = max
    -        else:
    -            self.maxLen = _MAX_INT
    -
    -        if exact > 0:
    -            self.maxLen = exact
    -            self.minLen = exact
    -
    -        self.name = _ustr(self)
    -        self.errmsg = "Expected " + self.name
    -        self.mayReturnEmpty = ( self.minLen == 0 )
    -        self.mayIndexError = False
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if instring[loc] in self.notChars:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        start = loc
    -        loc += 1
    -        notchars = self.notChars
    -        maxlen = min( start+self.maxLen, len(instring) )
    -        while loc < maxlen and \
    -              (instring[loc] not in notchars):
    -            loc += 1
    -
    -        if loc - start < self.minLen:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        return loc, instring[start:loc]
    -
    -    def __str__( self ):
    -        try:
    -            return super(CharsNotIn, self).__str__()
    -        except Exception:
    -            pass
    -
    -        if self.strRepr is None:
    -            if len(self.notChars) > 4:
    -                self.strRepr = "!W:(%s...)" % self.notChars[:4]
    -            else:
    -                self.strRepr = "!W:(%s)" % self.notChars
    -
    -        return self.strRepr
    -
    -class White(Token):
    -    """
    -    Special matching class for matching whitespace.  Normally, whitespace is ignored
    -    by pyparsing grammars.  This class is included when some whitespace structures
    -    are significant.  Define with a string containing the whitespace characters to be
    -    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
    -    as defined for the C{L{Word}} class.
    -    """
    -    whiteStrs = {
    -        " " : "",
    -        "\t": "",
    -        "\n": "",
    -        "\r": "",
    -        "\f": "",
    -        }
    -    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
    -        super(White,self).__init__()
    -        self.matchWhite = ws
    -        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
    -        #~ self.leaveWhitespace()
    -        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
    -        self.mayReturnEmpty = True
    -        self.errmsg = "Expected " + self.name
    -
    -        self.minLen = min
    -
    -        if max > 0:
    -            self.maxLen = max
    -        else:
    -            self.maxLen = _MAX_INT
    -
    -        if exact > 0:
    -            self.maxLen = exact
    -            self.minLen = exact
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if not(instring[ loc ] in self.matchWhite):
    -            raise ParseException(instring, loc, self.errmsg, self)
    -        start = loc
    -        loc += 1
    -        maxloc = start + self.maxLen
    -        maxloc = min( maxloc, len(instring) )
    -        while loc < maxloc and instring[loc] in self.matchWhite:
    -            loc += 1
    -
    -        if loc - start < self.minLen:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        return loc, instring[start:loc]
    -
    -
    -class _PositionToken(Token):
    -    def __init__( self ):
    -        super(_PositionToken,self).__init__()
    -        self.name=self.__class__.__name__
    -        self.mayReturnEmpty = True
    -        self.mayIndexError = False
    -
    -class GoToColumn(_PositionToken):
    -    """
    -    Token to advance to a specific column of input text; useful for tabular report scraping.
    -    """
    -    def __init__( self, colno ):
    -        super(GoToColumn,self).__init__()
    -        self.col = colno
    -
    -    def preParse( self, instring, loc ):
    -        if col(loc,instring) != self.col:
    -            instrlen = len(instring)
    -            if self.ignoreExprs:
    -                loc = self._skipIgnorables( instring, loc )
    -            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
    -                loc += 1
    -        return loc
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        thiscol = col( loc, instring )
    -        if thiscol > self.col:
    -            raise ParseException( instring, loc, "Text not in expected column", self )
    -        newloc = loc + self.col - thiscol
    -        ret = instring[ loc: newloc ]
    -        return newloc, ret
    -
    -
    -class LineStart(_PositionToken):
    -    """
    -    Matches if current position is at the beginning of a line within the parse string
    -    
    -    Example::
    -    
    -        test = '''\
    -        AAA this line
    -        AAA and this line
    -          AAA but not this one
    -        B AAA and definitely not this one
    -        '''
    -
    -        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
    -            print(t)
    -    
    -    Prints::
    -        ['AAA', ' this line']
    -        ['AAA', ' and this line']    
    -
    -    """
    -    def __init__( self ):
    -        super(LineStart,self).__init__()
    -        self.errmsg = "Expected start of line"
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if col(loc, instring) == 1:
    -            return loc, []
    -        raise ParseException(instring, loc, self.errmsg, self)
    -
    -class LineEnd(_PositionToken):
    -    """
    -    Matches if current position is at the end of a line within the parse string
    -    """
    -    def __init__( self ):
    -        super(LineEnd,self).__init__()
    -        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
    -        self.errmsg = "Expected end of line"
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if loc len(instring):
    -            return loc, []
    -        else:
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -class WordStart(_PositionToken):
    -    """
    -    Matches if the current position is at the beginning of a Word, and
    -    is not preceded by any character in a given set of C{wordChars}
    -    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
    -    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
    -    the string being parsed, or at the beginning of a line.
    -    """
    -    def __init__(self, wordChars = printables):
    -        super(WordStart,self).__init__()
    -        self.wordChars = set(wordChars)
    -        self.errmsg = "Not at the start of a word"
    -
    -    def parseImpl(self, instring, loc, doActions=True ):
    -        if loc != 0:
    -            if (instring[loc-1] in self.wordChars or
    -                instring[loc] not in self.wordChars):
    -                raise ParseException(instring, loc, self.errmsg, self)
    -        return loc, []
    -
    -class WordEnd(_PositionToken):
    -    """
    -    Matches if the current position is at the end of a Word, and
    -    is not followed by any character in a given set of C{wordChars}
    -    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
    -    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
    -    the string being parsed, or at the end of a line.
    -    """
    -    def __init__(self, wordChars = printables):
    -        super(WordEnd,self).__init__()
    -        self.wordChars = set(wordChars)
    -        self.skipWhitespace = False
    -        self.errmsg = "Not at the end of a word"
    -
    -    def parseImpl(self, instring, loc, doActions=True ):
    -        instrlen = len(instring)
    -        if instrlen>0 and loc maxExcLoc:
    -                    maxException = err
    -                    maxExcLoc = err.loc
    -            except IndexError:
    -                if len(instring) > maxExcLoc:
    -                    maxException = ParseException(instring,len(instring),e.errmsg,self)
    -                    maxExcLoc = len(instring)
    -            else:
    -                # save match among all matches, to retry longest to shortest
    -                matches.append((loc2, e))
    -
    -        if matches:
    -            matches.sort(key=lambda x: -x[0])
    -            for _,e in matches:
    -                try:
    -                    return e._parse( instring, loc, doActions )
    -                except ParseException as err:
    -                    err.__traceback__ = None
    -                    if err.loc > maxExcLoc:
    -                        maxException = err
    -                        maxExcLoc = err.loc
    -
    -        if maxException is not None:
    -            maxException.msg = self.errmsg
    -            raise maxException
    -        else:
    -            raise ParseException(instring, loc, "no defined alternatives to match", self)
    -
    -
    -    def __ixor__(self, other ):
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        return self.append( other ) #Or( [ self, other ] )
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
    -
    -        return self.strRepr
    -
    -    def checkRecursion( self, parseElementList ):
    -        subRecCheckList = parseElementList[:] + [ self ]
    -        for e in self.exprs:
    -            e.checkRecursion( subRecCheckList )
    -
    -
    -class MatchFirst(ParseExpression):
    -    """
    -    Requires that at least one C{ParseExpression} is found.
    -    If two expressions match, the first one listed is the one that will match.
    -    May be constructed using the C{'|'} operator.
    -
    -    Example::
    -        # construct MatchFirst using '|' operator
    -        
    -        # watch the order of expressions to match
    -        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
    -        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]
    -
    -        # put more selective expression first
    -        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
    -        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
    -    """
    -    def __init__( self, exprs, savelist = False ):
    -        super(MatchFirst,self).__init__(exprs, savelist)
    -        if self.exprs:
    -            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
    -        else:
    -            self.mayReturnEmpty = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        maxExcLoc = -1
    -        maxException = None
    -        for e in self.exprs:
    -            try:
    -                ret = e._parse( instring, loc, doActions )
    -                return ret
    -            except ParseException as err:
    -                if err.loc > maxExcLoc:
    -                    maxException = err
    -                    maxExcLoc = err.loc
    -            except IndexError:
    -                if len(instring) > maxExcLoc:
    -                    maxException = ParseException(instring,len(instring),e.errmsg,self)
    -                    maxExcLoc = len(instring)
    -
    -        # only got here if no expression matched, raise exception for match that made it the furthest
    -        else:
    -            if maxException is not None:
    -                maxException.msg = self.errmsg
    -                raise maxException
    -            else:
    -                raise ParseException(instring, loc, "no defined alternatives to match", self)
    -
    -    def __ior__(self, other ):
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass( other )
    -        return self.append( other ) #MatchFirst( [ self, other ] )
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
    -
    -        return self.strRepr
    -
    -    def checkRecursion( self, parseElementList ):
    -        subRecCheckList = parseElementList[:] + [ self ]
    -        for e in self.exprs:
    -            e.checkRecursion( subRecCheckList )
    -
    -
    -class Each(ParseExpression):
    -    """
    -    Requires all given C{ParseExpression}s to be found, but in any order.
    -    Expressions may be separated by whitespace.
    -    May be constructed using the C{'&'} operator.
    -
    -    Example::
    -        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
    -        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
    -        integer = Word(nums)
    -        shape_attr = "shape:" + shape_type("shape")
    -        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
    -        color_attr = "color:" + color("color")
    -        size_attr = "size:" + integer("size")
    -
    -        # use Each (using operator '&') to accept attributes in any order 
    -        # (shape and posn are required, color and size are optional)
    -        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
    -
    -        shape_spec.runTests('''
    -            shape: SQUARE color: BLACK posn: 100, 120
    -            shape: CIRCLE size: 50 color: BLUE posn: 50,80
    -            color:GREEN size:20 shape:TRIANGLE posn:20,40
    -            '''
    -            )
    -    prints::
    -        shape: SQUARE color: BLACK posn: 100, 120
    -        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
    -        - color: BLACK
    -        - posn: ['100', ',', '120']
    -          - x: 100
    -          - y: 120
    -        - shape: SQUARE
    -
    -
    -        shape: CIRCLE size: 50 color: BLUE posn: 50,80
    -        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
    -        - color: BLUE
    -        - posn: ['50', ',', '80']
    -          - x: 50
    -          - y: 80
    -        - shape: CIRCLE
    -        - size: 50
    -
    -
    -        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
    -        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
    -        - color: GREEN
    -        - posn: ['20', ',', '40']
    -          - x: 20
    -          - y: 40
    -        - shape: TRIANGLE
    -        - size: 20
    -    """
    -    def __init__( self, exprs, savelist = True ):
    -        super(Each,self).__init__(exprs, savelist)
    -        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
    -        self.skipWhitespace = True
    -        self.initExprGroups = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if self.initExprGroups:
    -            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
    -            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
    -            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
    -            self.optionals = opt1 + opt2
    -            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
    -            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
    -            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
    -            self.required += self.multirequired
    -            self.initExprGroups = False
    -        tmpLoc = loc
    -        tmpReqd = self.required[:]
    -        tmpOpt  = self.optionals[:]
    -        matchOrder = []
    -
    -        keepMatching = True
    -        while keepMatching:
    -            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
    -            failed = []
    -            for e in tmpExprs:
    -                try:
    -                    tmpLoc = e.tryParse( instring, tmpLoc )
    -                except ParseException:
    -                    failed.append(e)
    -                else:
    -                    matchOrder.append(self.opt1map.get(id(e),e))
    -                    if e in tmpReqd:
    -                        tmpReqd.remove(e)
    -                    elif e in tmpOpt:
    -                        tmpOpt.remove(e)
    -            if len(failed) == len(tmpExprs):
    -                keepMatching = False
    -
    -        if tmpReqd:
    -            missing = ", ".join(_ustr(e) for e in tmpReqd)
    -            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
    -
    -        # add any unmatched Optionals, in case they have default values defined
    -        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
    -
    -        resultlist = []
    -        for e in matchOrder:
    -            loc,results = e._parse(instring,loc,doActions)
    -            resultlist.append(results)
    -
    -        finalResults = sum(resultlist, ParseResults([]))
    -        return loc, finalResults
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
    -
    -        return self.strRepr
    -
    -    def checkRecursion( self, parseElementList ):
    -        subRecCheckList = parseElementList[:] + [ self ]
    -        for e in self.exprs:
    -            e.checkRecursion( subRecCheckList )
    -
    -
    -class ParseElementEnhance(ParserElement):
    -    """
    -    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
    -    """
    -    def __init__( self, expr, savelist=False ):
    -        super(ParseElementEnhance,self).__init__(savelist)
    -        if isinstance( expr, basestring ):
    -            if issubclass(ParserElement._literalStringClass, Token):
    -                expr = ParserElement._literalStringClass(expr)
    -            else:
    -                expr = ParserElement._literalStringClass(Literal(expr))
    -        self.expr = expr
    -        self.strRepr = None
    -        if expr is not None:
    -            self.mayIndexError = expr.mayIndexError
    -            self.mayReturnEmpty = expr.mayReturnEmpty
    -            self.setWhitespaceChars( expr.whiteChars )
    -            self.skipWhitespace = expr.skipWhitespace
    -            self.saveAsList = expr.saveAsList
    -            self.callPreparse = expr.callPreparse
    -            self.ignoreExprs.extend(expr.ignoreExprs)
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if self.expr is not None:
    -            return self.expr._parse( instring, loc, doActions, callPreParse=False )
    -        else:
    -            raise ParseException("",loc,self.errmsg,self)
    -
    -    def leaveWhitespace( self ):
    -        self.skipWhitespace = False
    -        self.expr = self.expr.copy()
    -        if self.expr is not None:
    -            self.expr.leaveWhitespace()
    -        return self
    -
    -    def ignore( self, other ):
    -        if isinstance( other, Suppress ):
    -            if other not in self.ignoreExprs:
    -                super( ParseElementEnhance, self).ignore( other )
    -                if self.expr is not None:
    -                    self.expr.ignore( self.ignoreExprs[-1] )
    -        else:
    -            super( ParseElementEnhance, self).ignore( other )
    -            if self.expr is not None:
    -                self.expr.ignore( self.ignoreExprs[-1] )
    -        return self
    -
    -    def streamline( self ):
    -        super(ParseElementEnhance,self).streamline()
    -        if self.expr is not None:
    -            self.expr.streamline()
    -        return self
    -
    -    def checkRecursion( self, parseElementList ):
    -        if self in parseElementList:
    -            raise RecursiveGrammarException( parseElementList+[self] )
    -        subRecCheckList = parseElementList[:] + [ self ]
    -        if self.expr is not None:
    -            self.expr.checkRecursion( subRecCheckList )
    -
    -    def validate( self, validateTrace=[] ):
    -        tmp = validateTrace[:]+[self]
    -        if self.expr is not None:
    -            self.expr.validate(tmp)
    -        self.checkRecursion( [] )
    -
    -    def __str__( self ):
    -        try:
    -            return super(ParseElementEnhance,self).__str__()
    -        except Exception:
    -            pass
    -
    -        if self.strRepr is None and self.expr is not None:
    -            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
    -        return self.strRepr
    -
    -
    -class FollowedBy(ParseElementEnhance):
    -    """
    -    Lookahead matching of the given parse expression.  C{FollowedBy}
    -    does I{not} advance the parsing position within the input string, it only
    -    verifies that the specified parse expression matches at the current
    -    position.  C{FollowedBy} always returns a null token list.
    -
    -    Example::
    -        # use FollowedBy to match a label only if it is followed by a ':'
    -        data_word = Word(alphas)
    -        label = data_word + FollowedBy(':')
    -        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
    -        
    -        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
    -    prints::
    -        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
    -    """
    -    def __init__( self, expr ):
    -        super(FollowedBy,self).__init__(expr)
    -        self.mayReturnEmpty = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        self.expr.tryParse( instring, loc )
    -        return loc, []
    -
    -
    -class NotAny(ParseElementEnhance):
    -    """
    -    Lookahead to disallow matching with the given parse expression.  C{NotAny}
    -    does I{not} advance the parsing position within the input string, it only
    -    verifies that the specified parse expression does I{not} match at the current
    -    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
    -    always returns a null token list.  May be constructed using the '~' operator.
    -
    -    Example::
    -        
    -    """
    -    def __init__( self, expr ):
    -        super(NotAny,self).__init__(expr)
    -        #~ self.leaveWhitespace()
    -        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
    -        self.mayReturnEmpty = True
    -        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        if self.expr.canParseNext(instring, loc):
    -            raise ParseException(instring, loc, self.errmsg, self)
    -        return loc, []
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "~{" + _ustr(self.expr) + "}"
    -
    -        return self.strRepr
    -
    -class _MultipleMatch(ParseElementEnhance):
    -    def __init__( self, expr, stopOn=None):
    -        super(_MultipleMatch, self).__init__(expr)
    -        self.saveAsList = True
    -        ender = stopOn
    -        if isinstance(ender, basestring):
    -            ender = ParserElement._literalStringClass(ender)
    -        self.not_ender = ~ender if ender is not None else None
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        self_expr_parse = self.expr._parse
    -        self_skip_ignorables = self._skipIgnorables
    -        check_ender = self.not_ender is not None
    -        if check_ender:
    -            try_not_ender = self.not_ender.tryParse
    -        
    -        # must be at least one (but first see if we are the stopOn sentinel;
    -        # if so, fail)
    -        if check_ender:
    -            try_not_ender(instring, loc)
    -        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
    -        try:
    -            hasIgnoreExprs = (not not self.ignoreExprs)
    -            while 1:
    -                if check_ender:
    -                    try_not_ender(instring, loc)
    -                if hasIgnoreExprs:
    -                    preloc = self_skip_ignorables( instring, loc )
    -                else:
    -                    preloc = loc
    -                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
    -                if tmptokens or tmptokens.haskeys():
    -                    tokens += tmptokens
    -        except (ParseException,IndexError):
    -            pass
    -
    -        return loc, tokens
    -        
    -class OneOrMore(_MultipleMatch):
    -    """
    -    Repetition of one or more of the given expression.
    -    
    -    Parameters:
    -     - expr - expression that must match one or more times
    -     - stopOn - (default=C{None}) - expression for a terminating sentinel
    -          (only required if the sentinel would ordinarily match the repetition 
    -          expression)          
    -
    -    Example::
    -        data_word = Word(alphas)
    -        label = data_word + FollowedBy(':')
    -        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
    -
    -        text = "shape: SQUARE posn: upper left color: BLACK"
    -        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
    -
    -        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
    -        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
    -        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
    -        
    -        # could also be written as
    -        (attr_expr * (1,)).parseString(text).pprint()
    -    """
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "{" + _ustr(self.expr) + "}..."
    -
    -        return self.strRepr
    -
    -class ZeroOrMore(_MultipleMatch):
    -    """
    -    Optional repetition of zero or more of the given expression.
    -    
    -    Parameters:
    -     - expr - expression that must match zero or more times
    -     - stopOn - (default=C{None}) - expression for a terminating sentinel
    -          (only required if the sentinel would ordinarily match the repetition 
    -          expression)          
    -
    -    Example: similar to L{OneOrMore}
    -    """
    -    def __init__( self, expr, stopOn=None):
    -        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
    -        self.mayReturnEmpty = True
    -        
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        try:
    -            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
    -        except (ParseException,IndexError):
    -            return loc, []
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "[" + _ustr(self.expr) + "]..."
    -
    -        return self.strRepr
    -
    -class _NullToken(object):
    -    def __bool__(self):
    -        return False
    -    __nonzero__ = __bool__
    -    def __str__(self):
    -        return ""
    -
    -_optionalNotMatched = _NullToken()
    -class Optional(ParseElementEnhance):
    -    """
    -    Optional matching of the given expression.
    -
    -    Parameters:
    -     - expr - expression that must match zero or more times
    -     - default (optional) - value to be returned if the optional expression is not found.
    -
    -    Example::
    -        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
    -        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
    -        zip.runTests('''
    -            # traditional ZIP code
    -            12345
    -            
    -            # ZIP+4 form
    -            12101-0001
    -            
    -            # invalid ZIP
    -            98765-
    -            ''')
    -    prints::
    -        # traditional ZIP code
    -        12345
    -        ['12345']
    -
    -        # ZIP+4 form
    -        12101-0001
    -        ['12101-0001']
    -
    -        # invalid ZIP
    -        98765-
    -             ^
    -        FAIL: Expected end of text (at char 5), (line:1, col:6)
    -    """
    -    def __init__( self, expr, default=_optionalNotMatched ):
    -        super(Optional,self).__init__( expr, savelist=False )
    -        self.saveAsList = self.expr.saveAsList
    -        self.defaultValue = default
    -        self.mayReturnEmpty = True
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        try:
    -            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
    -        except (ParseException,IndexError):
    -            if self.defaultValue is not _optionalNotMatched:
    -                if self.expr.resultsName:
    -                    tokens = ParseResults([ self.defaultValue ])
    -                    tokens[self.expr.resultsName] = self.defaultValue
    -                else:
    -                    tokens = [ self.defaultValue ]
    -            else:
    -                tokens = []
    -        return loc, tokens
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -
    -        if self.strRepr is None:
    -            self.strRepr = "[" + _ustr(self.expr) + "]"
    -
    -        return self.strRepr
    -
    -class SkipTo(ParseElementEnhance):
    -    """
    -    Token for skipping over all undefined text until the matched expression is found.
    -
    -    Parameters:
    -     - expr - target expression marking the end of the data to be skipped
    -     - include - (default=C{False}) if True, the target expression is also parsed 
    -          (the skipped text and target expression are returned as a 2-element list).
    -     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
    -          comments) that might contain false matches to the target expression
    -     - failOn - (default=C{None}) define expressions that are not allowed to be 
    -          included in the skipped test; if found before the target expression is found, 
    -          the SkipTo is not a match
    -
    -    Example::
    -        report = '''
    -            Outstanding Issues Report - 1 Jan 2000
    -
    -               # | Severity | Description                               |  Days Open
    -            -----+----------+-------------------------------------------+-----------
    -             101 | Critical | Intermittent system crash                 |          6
    -              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
    -              79 | Minor    | System slow when running too many reports |         47
    -            '''
    -        integer = Word(nums)
    -        SEP = Suppress('|')
    -        # use SkipTo to simply match everything up until the next SEP
    -        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
    -        # - parse action will call token.strip() for each matched token, i.e., the description body
    -        string_data = SkipTo(SEP, ignore=quotedString)
    -        string_data.setParseAction(tokenMap(str.strip))
    -        ticket_expr = (integer("issue_num") + SEP 
    -                      + string_data("sev") + SEP 
    -                      + string_data("desc") + SEP 
    -                      + integer("days_open"))
    -        
    -        for tkt in ticket_expr.searchString(report):
    -            print tkt.dump()
    -    prints::
    -        ['101', 'Critical', 'Intermittent system crash', '6']
    -        - days_open: 6
    -        - desc: Intermittent system crash
    -        - issue_num: 101
    -        - sev: Critical
    -        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
    -        - days_open: 14
    -        - desc: Spelling error on Login ('log|n')
    -        - issue_num: 94
    -        - sev: Cosmetic
    -        ['79', 'Minor', 'System slow when running too many reports', '47']
    -        - days_open: 47
    -        - desc: System slow when running too many reports
    -        - issue_num: 79
    -        - sev: Minor
    -    """
    -    def __init__( self, other, include=False, ignore=None, failOn=None ):
    -        super( SkipTo, self ).__init__( other )
    -        self.ignoreExpr = ignore
    -        self.mayReturnEmpty = True
    -        self.mayIndexError = False
    -        self.includeMatch = include
    -        self.asList = False
    -        if isinstance(failOn, basestring):
    -            self.failOn = ParserElement._literalStringClass(failOn)
    -        else:
    -            self.failOn = failOn
    -        self.errmsg = "No match found for "+_ustr(self.expr)
    -
    -    def parseImpl( self, instring, loc, doActions=True ):
    -        startloc = loc
    -        instrlen = len(instring)
    -        expr = self.expr
    -        expr_parse = self.expr._parse
    -        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
    -        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
    -        
    -        tmploc = loc
    -        while tmploc <= instrlen:
    -            if self_failOn_canParseNext is not None:
    -                # break if failOn expression matches
    -                if self_failOn_canParseNext(instring, tmploc):
    -                    break
    -                    
    -            if self_ignoreExpr_tryParse is not None:
    -                # advance past ignore expressions
    -                while 1:
    -                    try:
    -                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
    -                    except ParseBaseException:
    -                        break
    -            
    -            try:
    -                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
    -            except (ParseException, IndexError):
    -                # no match, advance loc in string
    -                tmploc += 1
    -            else:
    -                # matched skipto expr, done
    -                break
    -
    -        else:
    -            # ran off the end of the input string without matching skipto expr, fail
    -            raise ParseException(instring, loc, self.errmsg, self)
    -
    -        # build up return values
    -        loc = tmploc
    -        skiptext = instring[startloc:loc]
    -        skipresult = ParseResults(skiptext)
    -        
    -        if self.includeMatch:
    -            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
    -            skipresult += mat
    -
    -        return loc, skipresult
    -
    -class Forward(ParseElementEnhance):
    -    """
    -    Forward declaration of an expression to be defined later -
    -    used for recursive grammars, such as algebraic infix notation.
    -    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
    -
    -    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
    -    Specifically, '|' has a lower precedence than '<<', so that::
    -        fwdExpr << a | b | c
    -    will actually be evaluated as::
    -        (fwdExpr << a) | b | c
    -    thereby leaving b and c out as parseable alternatives.  It is recommended that you
    -    explicitly group the values inserted into the C{Forward}::
    -        fwdExpr << (a | b | c)
    -    Converting to use the '<<=' operator instead will avoid this problem.
    -
    -    See L{ParseResults.pprint} for an example of a recursive parser created using
    -    C{Forward}.
    -    """
    -    def __init__( self, other=None ):
    -        super(Forward,self).__init__( other, savelist=False )
    -
    -    def __lshift__( self, other ):
    -        if isinstance( other, basestring ):
    -            other = ParserElement._literalStringClass(other)
    -        self.expr = other
    -        self.strRepr = None
    -        self.mayIndexError = self.expr.mayIndexError
    -        self.mayReturnEmpty = self.expr.mayReturnEmpty
    -        self.setWhitespaceChars( self.expr.whiteChars )
    -        self.skipWhitespace = self.expr.skipWhitespace
    -        self.saveAsList = self.expr.saveAsList
    -        self.ignoreExprs.extend(self.expr.ignoreExprs)
    -        return self
    -        
    -    def __ilshift__(self, other):
    -        return self << other
    -    
    -    def leaveWhitespace( self ):
    -        self.skipWhitespace = False
    -        return self
    -
    -    def streamline( self ):
    -        if not self.streamlined:
    -            self.streamlined = True
    -            if self.expr is not None:
    -                self.expr.streamline()
    -        return self
    -
    -    def validate( self, validateTrace=[] ):
    -        if self not in validateTrace:
    -            tmp = validateTrace[:]+[self]
    -            if self.expr is not None:
    -                self.expr.validate(tmp)
    -        self.checkRecursion([])
    -
    -    def __str__( self ):
    -        if hasattr(self,"name"):
    -            return self.name
    -        return self.__class__.__name__ + ": ..."
    -
    -        # stubbed out for now - creates awful memory and perf issues
    -        self._revertClass = self.__class__
    -        self.__class__ = _ForwardNoRecurse
    -        try:
    -            if self.expr is not None:
    -                retString = _ustr(self.expr)
    -            else:
    -                retString = "None"
    -        finally:
    -            self.__class__ = self._revertClass
    -        return self.__class__.__name__ + ": " + retString
    -
    -    def copy(self):
    -        if self.expr is not None:
    -            return super(Forward,self).copy()
    -        else:
    -            ret = Forward()
    -            ret <<= self
    -            return ret
    -
    -class _ForwardNoRecurse(Forward):
    -    def __str__( self ):
    -        return "..."
    -
    -class TokenConverter(ParseElementEnhance):
    -    """
    -    Abstract subclass of C{ParseExpression}, for converting parsed results.
    -    """
    -    def __init__( self, expr, savelist=False ):
    -        super(TokenConverter,self).__init__( expr )#, savelist )
    -        self.saveAsList = False
    -
    -class Combine(TokenConverter):
    -    """
    -    Converter to concatenate all matching tokens to a single string.
    -    By default, the matching patterns must also be contiguous in the input string;
    -    this can be disabled by specifying C{'adjacent=False'} in the constructor.
    -
    -    Example::
    -        real = Word(nums) + '.' + Word(nums)
    -        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
    -        # will also erroneously match the following
    -        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
    -
    -        real = Combine(Word(nums) + '.' + Word(nums))
    -        print(real.parseString('3.1416')) # -> ['3.1416']
    -        # no match when there are internal spaces
    -        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
    -    """
    -    def __init__( self, expr, joinString="", adjacent=True ):
    -        super(Combine,self).__init__( expr )
    -        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
    -        if adjacent:
    -            self.leaveWhitespace()
    -        self.adjacent = adjacent
    -        self.skipWhitespace = True
    -        self.joinString = joinString
    -        self.callPreparse = True
    -
    -    def ignore( self, other ):
    -        if self.adjacent:
    -            ParserElement.ignore(self, other)
    -        else:
    -            super( Combine, self).ignore( other )
    -        return self
    -
    -    def postParse( self, instring, loc, tokenlist ):
    -        retToks = tokenlist.copy()
    -        del retToks[:]
    -        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
    -
    -        if self.resultsName and retToks.haskeys():
    -            return [ retToks ]
    -        else:
    -            return retToks
    -
    -class Group(TokenConverter):
    -    """
    -    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
    -
    -    Example::
    -        ident = Word(alphas)
    -        num = Word(nums)
    -        term = ident | num
    -        func = ident + Optional(delimitedList(term))
    -        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']
    -
    -        func = ident + Group(Optional(delimitedList(term)))
    -        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
    -    """
    -    def __init__( self, expr ):
    -        super(Group,self).__init__( expr )
    -        self.saveAsList = True
    -
    -    def postParse( self, instring, loc, tokenlist ):
    -        return [ tokenlist ]
    -
    -class Dict(TokenConverter):
    -    """
    -    Converter to return a repetitive expression as a list, but also as a dictionary.
    -    Each element can also be referenced using the first token in the expression as its key.
    -    Useful for tabular report scraping when the first column can be used as a item key.
    -
    -    Example::
    -        data_word = Word(alphas)
    -        label = data_word + FollowedBy(':')
    -        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
    -
    -        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
    -        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
    -        
    -        # print attributes as plain groups
    -        print(OneOrMore(attr_expr).parseString(text).dump())
    -        
    -        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
    -        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
    -        print(result.dump())
    -        
    -        # access named fields as dict entries, or output as dict
    -        print(result['shape'])        
    -        print(result.asDict())
    -    prints::
    -        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
    -
    -        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
    -        - color: light blue
    -        - posn: upper left
    -        - shape: SQUARE
    -        - texture: burlap
    -        SQUARE
    -        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
    -    See more examples at L{ParseResults} of accessing fields by results name.
    -    """
    -    def __init__( self, expr ):
    -        super(Dict,self).__init__( expr )
    -        self.saveAsList = True
    -
    -    def postParse( self, instring, loc, tokenlist ):
    -        for i,tok in enumerate(tokenlist):
    -            if len(tok) == 0:
    -                continue
    -            ikey = tok[0]
    -            if isinstance(ikey,int):
    -                ikey = _ustr(tok[0]).strip()
    -            if len(tok)==1:
    -                tokenlist[ikey] = _ParseResultsWithOffset("",i)
    -            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
    -                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
    -            else:
    -                dictvalue = tok.copy() #ParseResults(i)
    -                del dictvalue[0]
    -                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
    -                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
    -                else:
    -                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
    -
    -        if self.resultsName:
    -            return [ tokenlist ]
    -        else:
    -            return tokenlist
    -
    -
    -class Suppress(TokenConverter):
    -    """
    -    Converter for ignoring the results of a parsed expression.
    -
    -    Example::
    -        source = "a, b, c,d"
    -        wd = Word(alphas)
    -        wd_list1 = wd + ZeroOrMore(',' + wd)
    -        print(wd_list1.parseString(source))
    -
    -        # often, delimiters that are useful during parsing are just in the
    -        # way afterward - use Suppress to keep them out of the parsed output
    -        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
    -        print(wd_list2.parseString(source))
    -    prints::
    -        ['a', ',', 'b', ',', 'c', ',', 'd']
    -        ['a', 'b', 'c', 'd']
    -    (See also L{delimitedList}.)
    -    """
    -    def postParse( self, instring, loc, tokenlist ):
    -        return []
    -
    -    def suppress( self ):
    -        return self
    -
    -
    -class OnlyOnce(object):
    -    """
    -    Wrapper for parse actions, to ensure they are only called once.
    -    """
    -    def __init__(self, methodCall):
    -        self.callable = _trim_arity(methodCall)
    -        self.called = False
    -    def __call__(self,s,l,t):
    -        if not self.called:
    -            results = self.callable(s,l,t)
    -            self.called = True
    -            return results
    -        raise ParseException(s,l,"")
    -    def reset(self):
    -        self.called = False
    -
    -def traceParseAction(f):
    -    """
    -    Decorator for debugging parse actions. 
    -    
    -    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
    -    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.
    -
    -    Example::
    -        wd = Word(alphas)
    -
    -        @traceParseAction
    -        def remove_duplicate_chars(tokens):
    -            return ''.join(sorted(set(''.join(tokens))))
    -
    -        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
    -        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
    -    prints::
    -        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
    -        <3:
    -            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
    -        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
    -        try:
    -            ret = f(*paArgs)
    -        except Exception as exc:
    -            sys.stderr.write( "< ['aa', 'bb', 'cc']
    -        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
    -    """
    -    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
    -    if combine:
    -        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
    -    else:
    -        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
    -
    -def countedArray( expr, intExpr=None ):
    -    """
    -    Helper to define a counted list of expressions.
    -    This helper defines a pattern of the form::
    -        integer expr expr expr...
    -    where the leading integer tells how many expr expressions follow.
    -    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
    -    
    -    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.
    -
    -    Example::
    -        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']
    -
    -        # in this parser, the leading integer value is given in binary,
    -        # '10' indicating that 2 values are in the array
    -        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
    -        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
    -    """
    -    arrayExpr = Forward()
    -    def countFieldParseAction(s,l,t):
    -        n = t[0]
    -        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
    -        return []
    -    if intExpr is None:
    -        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
    -    else:
    -        intExpr = intExpr.copy()
    -    intExpr.setName("arrayLen")
    -    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
    -    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
    -
    -def _flatten(L):
    -    ret = []
    -    for i in L:
    -        if isinstance(i,list):
    -            ret.extend(_flatten(i))
    -        else:
    -            ret.append(i)
    -    return ret
    -
    -def matchPreviousLiteral(expr):
    -    """
    -    Helper to define an expression that is indirectly defined from
    -    the tokens matched in a previous expression, that is, it looks
    -    for a 'repeat' of a previous expression.  For example::
    -        first = Word(nums)
    -        second = matchPreviousLiteral(first)
    -        matchExpr = first + ":" + second
    -    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
    -    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
    -    If this is not desired, use C{matchPreviousExpr}.
    -    Do I{not} use with packrat parsing enabled.
    -    """
    -    rep = Forward()
    -    def copyTokenToRepeater(s,l,t):
    -        if t:
    -            if len(t) == 1:
    -                rep << t[0]
    -            else:
    -                # flatten t tokens
    -                tflat = _flatten(t.asList())
    -                rep << And(Literal(tt) for tt in tflat)
    -        else:
    -            rep << Empty()
    -    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
    -    rep.setName('(prev) ' + _ustr(expr))
    -    return rep
    -
    -def matchPreviousExpr(expr):
    -    """
    -    Helper to define an expression that is indirectly defined from
    -    the tokens matched in a previous expression, that is, it looks
    -    for a 'repeat' of a previous expression.  For example::
    -        first = Word(nums)
    -        second = matchPreviousExpr(first)
    -        matchExpr = first + ":" + second
    -    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
    -    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
    -    the expressions are evaluated first, and then compared, so
    -    C{"1"} is compared with C{"10"}.
    -    Do I{not} use with packrat parsing enabled.
    -    """
    -    rep = Forward()
    -    e2 = expr.copy()
    -    rep <<= e2
    -    def copyTokenToRepeater(s,l,t):
    -        matchTokens = _flatten(t.asList())
    -        def mustMatchTheseTokens(s,l,t):
    -            theseTokens = _flatten(t.asList())
    -            if  theseTokens != matchTokens:
    -                raise ParseException("",0,"")
    -        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
    -    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
    -    rep.setName('(prev) ' + _ustr(expr))
    -    return rep
    -
    -def _escapeRegexRangeChars(s):
    -    #~  escape these chars: ^-]
    -    for c in r"\^-]":
    -        s = s.replace(c,_bslash+c)
    -    s = s.replace("\n",r"\n")
    -    s = s.replace("\t",r"\t")
    -    return _ustr(s)
    -
    -def oneOf( strs, caseless=False, useRegex=True ):
    -    """
    -    Helper to quickly define a set of alternative Literals, and makes sure to do
    -    longest-first testing when there is a conflict, regardless of the input order,
    -    but returns a C{L{MatchFirst}} for best performance.
    -
    -    Parameters:
    -     - strs - a string of space-delimited literals, or a collection of string literals
    -     - caseless - (default=C{False}) - treat all literals as caseless
    -     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
    -          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
    -          if creating a C{Regex} raises an exception)
    -
    -    Example::
    -        comp_oper = oneOf("< = > <= >= !=")
    -        var = Word(alphas)
    -        number = Word(nums)
    -        term = var | number
    -        comparison_expr = term + comp_oper + term
    -        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
    -    prints::
    -        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
    -    """
    -    if caseless:
    -        isequal = ( lambda a,b: a.upper() == b.upper() )
    -        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
    -        parseElementClass = CaselessLiteral
    -    else:
    -        isequal = ( lambda a,b: a == b )
    -        masks = ( lambda a,b: b.startswith(a) )
    -        parseElementClass = Literal
    -
    -    symbols = []
    -    if isinstance(strs,basestring):
    -        symbols = strs.split()
    -    elif isinstance(strs, Iterable):
    -        symbols = list(strs)
    -    else:
    -        warnings.warn("Invalid argument to oneOf, expected string or iterable",
    -                SyntaxWarning, stacklevel=2)
    -    if not symbols:
    -        return NoMatch()
    -
    -    i = 0
    -    while i < len(symbols)-1:
    -        cur = symbols[i]
    -        for j,other in enumerate(symbols[i+1:]):
    -            if ( isequal(other, cur) ):
    -                del symbols[i+j+1]
    -                break
    -            elif ( masks(cur, other) ):
    -                del symbols[i+j+1]
    -                symbols.insert(i,other)
    -                cur = other
    -                break
    -        else:
    -            i += 1
    -
    -    if not caseless and useRegex:
    -        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
    -        try:
    -            if len(symbols)==len("".join(symbols)):
    -                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
    -            else:
    -                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
    -        except Exception:
    -            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
    -                    SyntaxWarning, stacklevel=2)
    -
    -
    -    # last resort, just use MatchFirst
    -    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
    -
    -def dictOf( key, value ):
    -    """
    -    Helper to easily and clearly define a dictionary by specifying the respective patterns
    -    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
    -    in the proper order.  The key pattern can include delimiting markers or punctuation,
    -    as long as they are suppressed, thereby leaving the significant key text.  The value
    -    pattern can include named results, so that the C{Dict} results can include named token
    -    fields.
    -
    -    Example::
    -        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
    -        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
    -        print(OneOrMore(attr_expr).parseString(text).dump())
    -        
    -        attr_label = label
    -        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
    -
    -        # similar to Dict, but simpler call format
    -        result = dictOf(attr_label, attr_value).parseString(text)
    -        print(result.dump())
    -        print(result['shape'])
    -        print(result.shape)  # object attribute access works too
    -        print(result.asDict())
    -    prints::
    -        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
    -        - color: light blue
    -        - posn: upper left
    -        - shape: SQUARE
    -        - texture: burlap
    -        SQUARE
    -        SQUARE
    -        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
    -    """
    -    return Dict( ZeroOrMore( Group ( key + value ) ) )
    -
    -def originalTextFor(expr, asString=True):
    -    """
    -    Helper to return the original, untokenized text for a given expression.  Useful to
    -    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
    -    revert separate tokens with intervening whitespace back to the original matching
    -    input text. By default, returns astring containing the original parsed text.  
    -       
    -    If the optional C{asString} argument is passed as C{False}, then the return value is a 
    -    C{L{ParseResults}} containing any results names that were originally matched, and a 
    -    single token containing the original matched text from the input string.  So if 
    -    the expression passed to C{L{originalTextFor}} contains expressions with defined
    -    results names, you must set C{asString} to C{False} if you want to preserve those
    -    results name values.
    -
    -    Example::
    -        src = "this is test  bold text  normal text "
    -        for tag in ("b","i"):
    -            opener,closer = makeHTMLTags(tag)
    -            patt = originalTextFor(opener + SkipTo(closer) + closer)
    -            print(patt.searchString(src)[0])
    -    prints::
    -        [' bold text ']
    -        ['text']
    -    """
    -    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
    -    endlocMarker = locMarker.copy()
    -    endlocMarker.callPreparse = False
    -    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
    -    if asString:
    -        extractText = lambda s,l,t: s[t._original_start:t._original_end]
    -    else:
    -        def extractText(s,l,t):
    -            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
    -    matchExpr.setParseAction(extractText)
    -    matchExpr.ignoreExprs = expr.ignoreExprs
    -    return matchExpr
    -
    -def ungroup(expr): 
    -    """
    -    Helper to undo pyparsing's default grouping of And expressions, even
    -    if all but one are non-empty.
    -    """
    -    return TokenConverter(expr).setParseAction(lambda t:t[0])
    -
    -def locatedExpr(expr):
    -    """
    -    Helper to decorate a returned token with its starting and ending locations in the input string.
    -    This helper adds the following results names:
    -     - locn_start = location where matched expression begins
    -     - locn_end = location where matched expression ends
    -     - value = the actual parsed results
    -
    -    Be careful if the input text contains C{} characters, you may want to call
    -    C{L{ParserElement.parseWithTabs}}
    -
    -    Example::
    -        wd = Word(alphas)
    -        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
    -            print(match)
    -    prints::
    -        [[0, 'ljsdf', 5]]
    -        [[8, 'lksdjjf', 15]]
    -        [[18, 'lkkjj', 23]]
    -    """
    -    locator = Empty().setParseAction(lambda s,l,t: l)
    -    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
    -
    -
    -# convenience constants for positional expressions
    -empty       = Empty().setName("empty")
    -lineStart   = LineStart().setName("lineStart")
    -lineEnd     = LineEnd().setName("lineEnd")
    -stringStart = StringStart().setName("stringStart")
    -stringEnd   = StringEnd().setName("stringEnd")
    -
    -_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
    -_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
    -_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
    -_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1)
    -_charRange = Group(_singleChar + Suppress("-") + _singleChar)
    -_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
    -
    -def srange(s):
    -    r"""
    -    Helper to easily define string ranges for use in Word construction.  Borrows
    -    syntax from regexp '[]' string range definitions::
    -        srange("[0-9]")   -> "0123456789"
    -        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
    -        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
    -    The input string must be enclosed in []'s, and the returned string is the expanded
    -    character set joined into a single string.
    -    The values enclosed in the []'s may be:
    -     - a single character
    -     - an escaped character with a leading backslash (such as C{\-} or C{\]})
    -     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
    -         (C{\0x##} is also supported for backwards compatibility) 
    -     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
    -     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
    -     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
    -    """
    -    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
    -    try:
    -        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
    -    except Exception:
    -        return ""
    -
    -def matchOnlyAtCol(n):
    -    """
    -    Helper method for defining parse actions that require matching at a specific
    -    column in the input text.
    -    """
    -    def verifyCol(strg,locn,toks):
    -        if col(locn,strg) != n:
    -            raise ParseException(strg,locn,"matched token not at column %d" % n)
    -    return verifyCol
    -
    -def replaceWith(replStr):
    -    """
    -    Helper method for common parse actions that simply return a literal value.  Especially
    -    useful when used with C{L{transformString}()}.
    -
    -    Example::
    -        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
    -        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
    -        term = na | num
    -        
    -        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
    -    """
    -    return lambda s,l,t: [replStr]
    -
    -def removeQuotes(s,l,t):
    -    """
    -    Helper parse action for removing quotation marks from parsed quoted strings.
    -
    -    Example::
    -        # by default, quotation marks are included in parsed results
    -        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
    -
    -        # use removeQuotes to strip quotation marks from parsed results
    -        quotedString.setParseAction(removeQuotes)
    -        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
    -    """
    -    return t[0][1:-1]
    -
    -def tokenMap(func, *args):
    -    """
    -    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
    -    args are passed, they are forwarded to the given function as additional arguments after
    -    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
    -    parsed data to an integer using base 16.
    -
    -    Example (compare the last to example in L{ParserElement.transformString}::
    -        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
    -        hex_ints.runTests('''
    -            00 11 22 aa FF 0a 0d 1a
    -            ''')
    -        
    -        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
    -        OneOrMore(upperword).runTests('''
    -            my kingdom for a horse
    -            ''')
    -
    -        wd = Word(alphas).setParseAction(tokenMap(str.title))
    -        OneOrMore(wd).setParseAction(' '.join).runTests('''
    -            now is the winter of our discontent made glorious summer by this sun of york
    -            ''')
    -    prints::
    -        00 11 22 aa FF 0a 0d 1a
    -        [0, 17, 34, 170, 255, 10, 13, 26]
    -
    -        my kingdom for a horse
    -        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
    -
    -        now is the winter of our discontent made glorious summer by this sun of york
    -        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
    -    """
    -    def pa(s,l,t):
    -        return [func(tokn, *args) for tokn in t]
    -
    -    try:
    -        func_name = getattr(func, '__name__', 
    -                            getattr(func, '__class__').__name__)
    -    except Exception:
    -        func_name = str(func)
    -    pa.__name__ = func_name
    -
    -    return pa
    -
    -upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
    -"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""
    -
    -downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
    -"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
    -    
    -def _makeTags(tagStr, xml):
    -    """Internal helper to construct opening and closing tag expressions, given a tag name"""
    -    if isinstance(tagStr,basestring):
    -        resname = tagStr
    -        tagStr = Keyword(tagStr, caseless=not xml)
    -    else:
    -        resname = tagStr.name
    -
    -    tagAttrName = Word(alphas,alphanums+"_-:")
    -    if (xml):
    -        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
    -        openTag = Suppress("<") + tagStr("tag") + \
    -                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
    -                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
    -    else:
    -        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
    -        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
    -        openTag = Suppress("<") + tagStr("tag") + \
    -                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
    -                Optional( Suppress("=") + tagAttrValue ) ))) + \
    -                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
    -    closeTag = Combine(_L("")
    -
    -    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
    -    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % resname)
    -    openTag.tag = resname
    -    closeTag.tag = resname
    -    return openTag, closeTag
    -
    -def makeHTMLTags(tagStr):
    -    """
    -    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
    -    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
    -
    -    Example::
    -        text = 'More info at the pyparsing wiki page'
    -        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
    -        a,a_end = makeHTMLTags("A")
    -        link_expr = a + SkipTo(a_end)("link_text") + a_end
    -        
    -        for link in link_expr.searchString(text):
    -            # attributes in the  tag (like "href" shown here) are also accessible as named results
    -            print(link.link_text, '->', link.href)
    -    prints::
    -        pyparsing -> http://pyparsing.wikispaces.com
    -    """
    -    return _makeTags( tagStr, False )
    -
    -def makeXMLTags(tagStr):
    -    """
    -    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
    -    tags only in the given upper/lower case.
    -
    -    Example: similar to L{makeHTMLTags}
    -    """
    -    return _makeTags( tagStr, True )
    -
    -def withAttribute(*args,**attrDict):
    -    """
    -    Helper to create a validating parse action to be used with start tags created
    -    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
    -    with a required attribute value, to avoid false matches on common tags such as
    -    C{} or C{
    }. - - Call C{withAttribute} with a series of attribute names and values. Specify the list - of filter attributes names and values as: - - keyword arguments, as in C{(align="right")}, or - - as an explicit dict with C{**} operator, when an attribute name is also a Python - reserved word, as in C{**{"class":"Customer", "align":"right"}} - - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) - For attribute names with a namespace prefix, you must use the second form. Attribute - names are matched insensitive to upper/lower case. - - If just testing for C{class} (with or without a namespace), use C{L{withClass}}. - - To verify that the attribute exists, but without specifying a value, pass - C{withAttribute.ANY_VALUE} as the value. - - Example:: - html = ''' -
    - Some text -
    1 4 0 1 0
    -
    1,3 2,3 1,1
    -
    this has no type
    -
    - - ''' - div,div_end = makeHTMLTags("div") - - # only match div tag having a type attribute with value "grid" - div_grid = div().setParseAction(withAttribute(type="grid")) - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - # construct a match with any div tag having a type attribute, regardless of the value - div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - prints:: - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - if args: - attrs = args[:] - else: - attrs = attrDict.items() - attrs = [(k,v) for k,v in attrs] - def pa(s,l,tokens): - for attrName,attrValue in attrs: - if attrName not in tokens: - raise ParseException(s,l,"no matching attribute " + attrName) - if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: - raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % - (attrName, tokens[attrName], attrValue)) - return pa -withAttribute.ANY_VALUE = object() - -def withClass(classname, namespace=''): - """ - Simplified version of C{L{withAttribute}} when matching on a div class - made - difficult because C{class} is a reserved word in Python. - - Example:: - html = ''' -
    - Some text -
    1 4 0 1 0
    -
    1,3 2,3 1,1
    -
    this <div> has no class
    -
    - - ''' - div,div_end = makeHTMLTags("div") - div_grid = div().setParseAction(withClass("grid")) - - grid_expr = div_grid + SkipTo(div | div_end)("body") - for grid_header in grid_expr.searchString(html): - print(grid_header.body) - - div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) - div_expr = div_any_type + SkipTo(div | div_end)("body") - for div_header in div_expr.searchString(html): - print(div_header.body) - prints:: - 1 4 0 1 0 - - 1 4 0 1 0 - 1,3 2,3 1,1 - """ - classattr = "%s:class" % namespace if namespace else "class" - return withAttribute(**{classattr : classname}) - -opAssoc = _Constants() -opAssoc.LEFT = object() -opAssoc.RIGHT = object() - -def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): - """ - Helper method for constructing grammars of expressions made up of - operators working in a precedence hierarchy. Operators may be unary or - binary, left- or right-associative. Parse actions can also be attached - to operator expressions. The generated parser will also recognize the use - of parentheses to override operator precedences (see example below). - - Note: if you define a deep operator list, you may see performance issues - when using infixNotation. See L{ParserElement.enablePackrat} for a - mechanism to potentially improve your parser performance. - - Parameters: - - baseExpr - expression representing the most basic element for the nested - - opList - list of tuples, one for each operator precedence level in the - expression grammar; each tuple is of the form - (opExpr, numTerms, rightLeftAssoc, parseAction), where: - - opExpr is the pyparsing expression for the operator; - may also be a string, which will be converted to a Literal; - if numTerms is 3, opExpr is a tuple of two expressions, for the - two operators separating the 3 terms - - numTerms is the number of terms for this operator (must - be 1, 2, or 3) - - rightLeftAssoc is the indicator whether the operator is - right or left associative, using the pyparsing-defined - constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. - - parseAction is the parse action to be associated with - expressions matching this operator expression (the - parse action tuple member may be omitted); if the parse action - is passed a tuple or list of functions, this is equivalent to - calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) - - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) - - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) - - Example:: - # simple example of four-function arithmetic with ints and variable names - integer = pyparsing_common.signed_integer - varname = pyparsing_common.identifier - - arith_expr = infixNotation(integer | varname, - [ - ('-', 1, opAssoc.RIGHT), - (oneOf('* /'), 2, opAssoc.LEFT), - (oneOf('+ -'), 2, opAssoc.LEFT), - ]) - - arith_expr.runTests(''' - 5+3*6 - (5+3)*6 - -2--11 - ''', fullDump=False) - prints:: - 5+3*6 - [[5, '+', [3, '*', 6]]] - - (5+3)*6 - [[[5, '+', 3], '*', 6]] - - -2--11 - [[['-', 2], '-', ['-', 11]]] - """ - ret = Forward() - lastExpr = baseExpr | ( lpar + ret + rpar ) - for i,operDef in enumerate(opList): - opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] - termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr - if arity == 3: - if opExpr is None or len(opExpr) != 2: - raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") - opExpr1, opExpr2 = opExpr - thisExpr = Forward().setName(termName) - if rightLeftAssoc == opAssoc.LEFT: - if arity == 1: - matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) - else: - matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ - Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - elif rightLeftAssoc == opAssoc.RIGHT: - if arity == 1: - # try to avoid LR with this extra test - if not isinstance(opExpr, Optional): - opExpr = Optional(opExpr) - matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) - else: - matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ - Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - else: - raise ValueError("operator must indicate right or left associativity") - if pa: - if isinstance(pa, (tuple, list)): - matchExpr.setParseAction(*pa) - else: - matchExpr.setParseAction(pa) - thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) - lastExpr = thisExpr - ret <<= lastExpr - return ret - -operatorPrecedence = infixNotation -"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" - -dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") -sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") -quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| - Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") -unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") - -def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): - """ - Helper method for defining nested lists enclosed in opening and closing - delimiters ("(" and ")" are the default). - - Parameters: - - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression - - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression - - content - expression for items within the nested lists (default=C{None}) - - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) - - If an expression is not provided for the content argument, the nested - expression will capture all whitespace-delimited content between delimiters - as a list of separate values. - - Use the C{ignoreExpr} argument to define expressions that may contain - opening or closing characters that should not be treated as opening - or closing characters for nesting, such as quotedString or a comment - expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. - The default is L{quotedString}, but if no expressions are to be ignored, - then pass C{None} for this argument. - - Example:: - data_type = oneOf("void int short long char float double") - decl_data_type = Combine(data_type + Optional(Word('*'))) - ident = Word(alphas+'_', alphanums+'_') - number = pyparsing_common.number - arg = Group(decl_data_type + ident) - LPAR,RPAR = map(Suppress, "()") - - code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) - - c_function = (decl_data_type("type") - + ident("name") - + LPAR + Optional(delimitedList(arg), [])("args") + RPAR - + code_body("body")) - c_function.ignore(cStyleComment) - - source_code = ''' - int is_odd(int x) { - return (x%2); - } - - int dec_to_hex(char hchar) { - if (hchar >= '0' && hchar <= '9') { - return (ord(hchar)-ord('0')); - } else { - return (10+ord(hchar)-ord('A')); - } - } - ''' - for func in c_function.searchString(source_code): - print("%(name)s (%(type)s) args: %(args)s" % func) - - prints:: - is_odd (int) args: [['int', 'x']] - dec_to_hex (int) args: [['char', 'hchar']] - """ - if opener == closer: - raise ValueError("opening and closing strings cannot be the same") - if content is None: - if isinstance(opener,basestring) and isinstance(closer,basestring): - if len(opener) == 1 and len(closer)==1: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS - ).setParseAction(lambda t:t[0].strip())) - else: - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - ~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - raise ValueError("opening and closing arguments must be strings if no content expression is given") - ret = Forward() - if ignoreExpr is not None: - ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) - else: - ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) - ret.setName('nested %s%s expression' % (opener,closer)) - return ret - -def indentedBlock(blockStatementExpr, indentStack, indent=True): - """ - Helper method for defining space-delimited indentation blocks, such as - those used to define block statements in Python source code. - - Parameters: - - blockStatementExpr - expression defining syntax of statement that - is repeated within the indented block - - indentStack - list created by caller to manage indentation stack - (multiple statementWithIndentedBlock expressions within a single grammar - should share a common indentStack) - - indent - boolean indicating whether block must be indented beyond the - the current level; set to False for block of left-most statements - (default=C{True}) - - A valid block must contain at least one C{blockStatement}. - - Example:: - data = ''' - def A(z): - A1 - B = 100 - G = A2 - A2 - A3 - B - def BB(a,b,c): - BB1 - def BBA(): - bba1 - bba2 - bba3 - C - D - def spam(x,y): - def eggs(z): - pass - ''' - - - indentStack = [1] - stmt = Forward() - - identifier = Word(alphas, alphanums) - funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") - func_body = indentedBlock(stmt, indentStack) - funcDef = Group( funcDecl + func_body ) - - rvalue = Forward() - funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") - rvalue << (funcCall | identifier | Word(nums)) - assignment = Group(identifier + "=" + rvalue) - stmt << ( funcDef | assignment | identifier ) - - module_body = OneOrMore(stmt) - - parseTree = module_body.parseString(data) - parseTree.pprint() - prints:: - [['def', - 'A', - ['(', 'z', ')'], - ':', - [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], - 'B', - ['def', - 'BB', - ['(', 'a', 'b', 'c', ')'], - ':', - [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], - 'C', - 'D', - ['def', - 'spam', - ['(', 'x', 'y', ')'], - ':', - [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] - """ - def checkPeerIndent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if curCol != indentStack[-1]: - if curCol > indentStack[-1]: - raise ParseFatalException(s,l,"illegal nesting") - raise ParseException(s,l,"not a peer entry") - - def checkSubIndent(s,l,t): - curCol = col(l,s) - if curCol > indentStack[-1]: - indentStack.append( curCol ) - else: - raise ParseException(s,l,"not a subentry") - - def checkUnindent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): - raise ParseException(s,l,"not an unindent") - indentStack.pop() - - NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) - INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') - PEER = Empty().setParseAction(checkPeerIndent).setName('') - UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') - if indent: - smExpr = Group( Optional(NL) + - #~ FollowedBy(blockStatementExpr) + - INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) - else: - smExpr = Group( Optional(NL) + - (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) - blockStatementExpr.ignore(_bslash + LineEnd()) - return smExpr.setName('indented block') - -alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") -punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") - -anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) -_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) -commonHTMLEntity = Regex('&(?P' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") -def replaceHTMLEntity(t): - """Helper parser action to replace common HTML entities with their special characters""" - return _htmlEntityMap.get(t.entity) - -# it's easy to get these comment structures wrong - they're very common, so may as well make them available -cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") -"Comment of the form C{/* ... */}" - -htmlComment = Regex(r"").setName("HTML comment") -"Comment of the form C{}" - -restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") -dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") -"Comment of the form C{// ... (to end of line)}" - -cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") -"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" - -javaStyleComment = cppStyleComment -"Same as C{L{cppStyleComment}}" - -pythonStyleComment = Regex(r"#.*").setName("Python style comment") -"Comment of the form C{# ... (to end of line)}" - -_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + - Optional( Word(" \t") + - ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") -commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") -"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. - This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" - -# some other useful expressions - using lower-case class name since we are really using this as a namespace -class pyparsing_common: - """ - Here are some common low-level expressions that may be useful in jump-starting parser development: - - numeric forms (L{integers}, L{reals}, L{scientific notation}) - - common L{programming identifiers} - - network addresses (L{MAC}, L{IPv4}, L{IPv6}) - - ISO8601 L{dates} and L{datetime} - - L{UUID} - - L{comma-separated list} - Parse actions: - - C{L{convertToInteger}} - - C{L{convertToFloat}} - - C{L{convertToDate}} - - C{L{convertToDatetime}} - - C{L{stripHTMLTags}} - - C{L{upcaseTokens}} - - C{L{downcaseTokens}} - - Example:: - pyparsing_common.number.runTests(''' - # any int or real number, returned as the appropriate type - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.fnumber.runTests(''' - # any int or real number, returned as float - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - ''') - - pyparsing_common.hex_integer.runTests(''' - # hex numbers - 100 - FF - ''') - - pyparsing_common.fraction.runTests(''' - # fractions - 1/2 - -3/4 - ''') - - pyparsing_common.mixed_integer.runTests(''' - # mixed fractions - 1 - 1/2 - -3/4 - 1-3/4 - ''') - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(''' - # uuid - 12345678-1234-5678-1234-567812345678 - ''') - prints:: - # any int or real number, returned as the appropriate type - 100 - [100] - - -100 - [-100] - - +100 - [100] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # any int or real number, returned as float - 100 - [100.0] - - -100 - [-100.0] - - +100 - [100.0] - - 3.14159 - [3.14159] - - 6.02e23 - [6.02e+23] - - 1e-12 - [1e-12] - - # hex numbers - 100 - [256] - - FF - [255] - - # fractions - 1/2 - [0.5] - - -3/4 - [-0.75] - - # mixed fractions - 1 - [1] - - 1/2 - [0.5] - - -3/4 - [-0.75] - - 1-3/4 - [1.75] - - # uuid - 12345678-1234-5678-1234-567812345678 - [UUID('12345678-1234-5678-1234-567812345678')] - """ - - convertToInteger = tokenMap(int) - """ - Parse action for converting parsed integers to Python int - """ - - convertToFloat = tokenMap(float) - """ - Parse action for converting parsed numbers to Python float - """ - - integer = Word(nums).setName("integer").setParseAction(convertToInteger) - """expression that parses an unsigned integer, returns an int""" - - hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) - """expression that parses a hexadecimal integer, returns an int""" - - signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) - """expression that parses an integer with optional leading sign, returns an int""" - - fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") - """fractional expression of an integer divided by an integer, returns a float""" - fraction.addParseAction(lambda t: t[0]/t[-1]) - - mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") - """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" - mixed_integer.addParseAction(sum) - - real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) - """expression that parses a floating point number and returns a float""" - - sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) - """expression that parses a floating point number with optional scientific notation and returns a float""" - - # streamlining this expression makes the docs nicer-looking - number = (sci_real | real | signed_integer).streamline() - """any numeric expression, returns the corresponding Python type""" - - fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) - """any int or real number, returned as float""" - - identifier = Word(alphas+'_', alphanums+'_').setName("identifier") - """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" - - ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") - "IPv4 address (C{0.0.0.0 - 255.255.255.255})" - - _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") - _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") - _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") - _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) - _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") - ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") - "IPv6 address (long, short, or mixed form)" - - mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") - "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" - - @staticmethod - def convertToDate(fmt="%Y-%m-%d"): - """ - Helper to create a parse action for converting parsed date string to Python datetime.date - - Params - - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) - - Example:: - date_expr = pyparsing_common.iso8601_date.copy() - date_expr.setParseAction(pyparsing_common.convertToDate()) - print(date_expr.parseString("1999-12-31")) - prints:: - [datetime.date(1999, 12, 31)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt).date() - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - @staticmethod - def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): - """ - Helper to create a parse action for converting parsed datetime string to Python datetime.datetime - - Params - - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) - - Example:: - dt_expr = pyparsing_common.iso8601_datetime.copy() - dt_expr.setParseAction(pyparsing_common.convertToDatetime()) - print(dt_expr.parseString("1999-12-31T23:59:59.999")) - prints:: - [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] - """ - def cvt_fn(s,l,t): - try: - return datetime.strptime(t[0], fmt) - except ValueError as ve: - raise ParseException(s, l, str(ve)) - return cvt_fn - - iso8601_date = Regex(r'(?P\d{4})(?:-(?P\d\d)(?:-(?P\d\d))?)?').setName("ISO8601 date") - "ISO8601 date (C{yyyy-mm-dd})" - - iso8601_datetime = Regex(r'(?P\d{4})-(?P\d\d)-(?P\d\d)[T ](?P\d\d):(?P\d\d)(:(?P\d\d(\.\d*)?)?)?(?PZ|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") - "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" - - uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") - "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" - - _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() - @staticmethod - def stripHTMLTags(s, l, tokens): - """ - Parse action to remove HTML tags from web page HTML source - - Example:: - # strip HTML links from normal text - text = 'More info at the
    pyparsing wiki page' - td,td_end = makeHTMLTags("TD") - table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end - - print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' - """ - return pyparsing_common._html_stripper.transformString(tokens[0]) - - _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') - + Optional( White(" \t") ) ) ).streamline().setName("commaItem") - comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") - """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" - - upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) - """Parse action to convert tokens to upper case.""" - - downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) - """Parse action to convert tokens to lower case.""" - - -if __name__ == "__main__": - - selectToken = CaselessLiteral("select") - fromToken = CaselessLiteral("from") - - ident = Word(alphas, alphanums + "_$") - - columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - columnNameList = Group(delimitedList(columnName)).setName("columns") - columnSpec = ('*' | columnNameList) - - tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) - tableNameList = Group(delimitedList(tableName)).setName("tables") - - simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") - - # demo runTests method, including embedded comments in test string - simpleSQL.runTests(""" - # '*' as column list and dotted table name - select * from SYS.XYZZY - - # caseless match on "SELECT", and casts back to "select" - SELECT * from XYZZY, ABC - - # list of column names, and mixed case SELECT keyword - Select AA,BB,CC from Sys.dual - - # multiple tables - Select A, B, C from Sys.dual, Table2 - - # invalid SELECT keyword - should fail - Xelect A, B, C from Sys.dual - - # incomplete command - should fail - Select - - # invalid column name - should fail - Select ^^^ frox Sys.dual - - """) - - pyparsing_common.number.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - # any int or real number, returned as float - pyparsing_common.fnumber.runTests(""" - 100 - -100 - +100 - 3.14159 - 6.02e23 - 1e-12 - """) - - pyparsing_common.hex_integer.runTests(""" - 100 - FF - """) - - import uuid - pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) - pyparsing_common.uuid.runTests(""" - 12345678-1234-5678-1234-567812345678 - """) diff --git a/env/lib/python3.8/site-packages/pkg_resources/_vendor/six.py b/env/lib/python3.8/site-packages/pkg_resources/_vendor/six.py deleted file mode 100644 index 190c0239..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/_vendor/six.py +++ /dev/null @@ -1,868 +0,0 @@ -"""Utilities for writing code that runs on Python 2 and 3""" - -# Copyright (c) 2010-2015 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson " -__version__ = "1.10.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - get_source = get_code # same as get_code - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes - -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") - - -if PY3: - def b(s): - return s.encode("latin-1") - - def u(s): - return s - unichr = chr - import struct - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" -else: - def b(s): - return s - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): - raise tp, value, tb -""") - - -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - if from_value is None: - raise value - raise value from from_value -""") -elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - raise value from from_value -""") -else: - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper -else: - wraps = functools.wraps - - -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(meta): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/env/lib/python3.8/site-packages/pkg_resources/extern/__init__.py b/env/lib/python3.8/site-packages/pkg_resources/extern/__init__.py deleted file mode 100644 index c1eb9e99..00000000 --- a/env/lib/python3.8/site-packages/pkg_resources/extern/__init__.py +++ /dev/null @@ -1,73 +0,0 @@ -import sys - - -class VendorImporter: - """ - A PEP 302 meta path importer for finding optionally-vendored - or otherwise naturally-installed packages from root_name. - """ - - def __init__(self, root_name, vendored_names=(), vendor_pkg=None): - self.root_name = root_name - self.vendored_names = set(vendored_names) - self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') - - @property - def search_path(self): - """ - Search first the vendor package then as a natural package. - """ - yield self.vendor_pkg + '.' - yield '' - - def find_module(self, fullname, path=None): - """ - Return self when fullname starts with root_name and the - target module is one vendored through this importer. - """ - root, base, target = fullname.partition(self.root_name + '.') - if root: - return - if not any(map(target.startswith, self.vendored_names)): - return - return self - - def load_module(self, fullname): - """ - Iterate over the search path to locate and load fullname. - """ - root, base, target = fullname.partition(self.root_name + '.') - for prefix in self.search_path: - try: - extant = prefix + target - __import__(extant) - mod = sys.modules[extant] - sys.modules[fullname] = mod - # mysterious hack: - # Remove the reference to the extant package/module - # on later Python versions to cause relative imports - # in the vendor package to resolve the same modules - # as those going through this importer. - if prefix and sys.version_info > (3, 3): - del sys.modules[extant] - return mod - except ImportError: - pass - else: - raise ImportError( - "The '{target}' package is required; " - "normally this is bundled with this package so if you get " - "this warning, consult the packager of your " - "distribution.".format(**locals()) - ) - - def install(self): - """ - Install this importer into sys.meta_path if not already present. - """ - if self not in sys.meta_path: - sys.meta_path.append(self) - - -names = 'packaging', 'pyparsing', 'six', 'appdirs' -VendorImporter(__name__, names).install() diff --git a/env/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0f01eb397f2770d6c16a6f651bf6f8b4b4c2d1f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2452 zcmZ`)U2hvj6rI^m+ey<3p@deY8UdnMYHdV$s6;_UZG|dORJG88Rak92<9HK$XFD@) zVzYk15sy3|Azquu{*C^OdF82p0SUpqv$o?VVywNM-TAuro^#K9ckWz+K)dC5KE&X_7o0ik4gb z5&{oaqQ*Wxci_<5W>nkaZ>r$ z3~haRn)S6Xc4OhW^FZ5JiDHm;g>6&=NwL4%3~Zpqpr_Cc6``r2K{%ZGTekahDB4;*3GugjJUqYOB)V_ z(Xj4W#HBynmT!q{#` zwqC$l8CIR+qV>~!Z2e(c*hb|Bdf^z_j9hwcZQ-X4Fr_v?7j3YUYGI?wsS_U0A;9`h zDo?lIV2!7faFYh`dkda3P^>KIBCi$=s{}#51CRb4%o!*=1Orm<-6cQ%Gz}+r%diZ# z$TR{_q8X*c1bbl_T_n@Ej9s7JB4wzaLOdbAsn5u7bVh#x^+m0ne7yweKBz@%1d~vsh#tW0Nbe-jNH&mN97b#h zGUZDSoInr(noIF(Nlkj61cVMPIL*C8DmR)PNXq+P47i+f5*Wh1x`hN-a;re>gR|M)4pb5xUP(pt_NuG^Tr(EzBCkdC`BvEVVQ>{?45Xy`d z5<*=>^8uQxXdIctrJOG6h3 smL1v{0_Sj_G((pYx59?#v{oPC_WyUTt=*~u`T}n -Copyright © 2009-2014 Florent Xicluna -Copyright © 2014-2020 Ian Lee - -Licensed under the terms of the Expat License - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation files -(the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/METADATA b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/METADATA deleted file mode 100644 index 7287b4e5..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/METADATA +++ /dev/null @@ -1,1035 +0,0 @@ -Metadata-Version: 2.1 -Name: pycodestyle -Version: 2.6.0 -Summary: Python style guide checker -Home-page: https://pycodestyle.readthedocs.io/ -Author: Johann C. Rocholl -Author-email: johann@rocholl.net -Maintainer: Ian Lee -Maintainer-email: IanLee1521@gmail.com -License: Expat license -Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8 -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* - -pycodestyle (formerly called pep8) - Python style guide checker -=============================================================== - -.. image:: https://img.shields.io/travis/PyCQA/pycodestyle.svg - :target: https://travis-ci.org/PyCQA/pycodestyle - :alt: Build status - -.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest - :target: https://pycodestyle.readthedocs.io - :alt: Documentation Status - -.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg - :target: https://pypi.org/project/pycodestyle/ - :alt: Wheel Status - -.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg - :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle - :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - -pycodestyle is a tool to check your Python code against some of the style -conventions in `PEP 8`_. - -.. _PEP 8: http://www.python.org/dev/peps/pep-0008/ - -.. note:: - - This package used to be called ``pep8`` but was renamed to ``pycodestyle`` - to reduce confusion. Further discussion can be found `in the issue where - Guido requested this - change `_, or in the - lightning talk at PyCon 2016 by @IanLee1521: - `slides `_ - `video `_. - -Features --------- - -* Plugin architecture: Adding new checks is easy. - -* Parseable output: Jump to error location in your editor. - -* Small: Just one Python file, requires only stdlib. You can use just - the ``pycodestyle.py`` file for this purpose. - -* Comes with a comprehensive test suite. - -Installation ------------- - -You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: - - $ pip install pycodestyle - $ pip install --upgrade pycodestyle - $ pip uninstall pycodestyle - -There's also a package for Debian/Ubuntu, but it's not always the -latest version. - -Example usage and output ------------------------- - -:: - - $ pycodestyle --first optparse.py - optparse.py:69:11: E401 multiple imports on one line - optparse.py:77:1: E302 expected 2 blank lines, found 1 - optparse.py:88:5: E301 expected 1 blank line, found 0 - optparse.py:222:34: W602 deprecated form of raising exception - optparse.py:347:31: E211 whitespace before '(' - optparse.py:357:17: E201 whitespace after '{' - optparse.py:472:29: E221 multiple spaces before operator - optparse.py:544:21: W601 .has_key() is deprecated, use 'in' - -You can also make ``pycodestyle.py`` show the source code for each error, and -even the relevant text from PEP 8:: - - $ pycodestyle --show-source --show-pep8 testsuite/E40.py - testsuite/E40.py:2:10: E401 multiple imports on one line - import os, sys - ^ - Imports should usually be on separate lines. - - Okay: import os\nimport sys - E401: import sys, os - - -Or you can display how often each error was found:: - - $ pycodestyle --statistics -qq Python-2.5/Lib - 232 E201 whitespace after '[' - 599 E202 whitespace before ')' - 631 E203 whitespace before ',' - 842 E211 whitespace before '(' - 2531 E221 multiple spaces before operator - 4473 E301 expected 1 blank line, found 0 - 4006 E302 expected 2 blank lines, found 1 - 165 E303 too many blank lines (4) - 325 E401 multiple imports on one line - 3615 E501 line too long (82 characters) - 612 W601 .has_key() is deprecated, use 'in' - 1188 W602 deprecated form of raising exception - -Links ------ - -* `Read the documentation `_ - -* `Fork me on GitHub `_ - - -Changelog -========= - -2.6.0 (2020-05-11) ------------------- - -Announcements: - -* Anthony Sottile (@asottile) joined the team as a core developer. :tada: - -Changes: - -* E306: fix detection inside ``async def``. PR #929. -* E301: fix regression disallowing decorated one-liners. PR #927. -* E714: fix false positive with chained ``is not``. PR #931. - - -2.6.0a1 (2020-04-23) --------------------- - -New checks: - -* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847. - -Changes: - -* E117: fix indentation using tabs by treating as 8-space indents. PR #837. -* E721: fix false positive with names containg ``istype``. PR #850. -* E741: allow ``l`` as a named argument in a function call. PR #853. -* E302: fix false-negative with decorated functions. PR #859. -* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875. -* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834. -* Add support for assignment expressions ``:=`` (PEP 572). PR #879. -* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918. -* Add support for python 3.8. -* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897. -* Support visual indent for continuation lines for ``with`` / ``assert`` / - ``raise``. PR #912. -* E302: allow two blank lines after a block of one-liners. PR #913. -* E302: allow two-and-fewer newlines at the top of the file. PR #919. - - -2.5.0 (2019-01-29) ------------------- - -New checks: - -* E117: Over-indented code blocks -* W505: Maximum doc-string length only when configured with --max-doc-length - -Changes: - -* Remove support for EOL Python 2.6 and 3.3. PR #720. -* Add E117 error for over-indented code blocks. -* Allow W605 to be silenced by `# noqa` and fix the position reported by W605 -* Allow users to omit blank lines around one-liner definitions of classes and - functions -* Include the function return annotation (``->``) as requiring surrounding - whitespace only on Python 3 -* Verify that only names can follow ``await``. Previously we allowed numbers - and strings. -* Add support for Python 3.7 -* Fix detection of annotated argument defaults for E252 -* Correct the position reported by W504 - - -2.4.0 (2018-04-10) ------------------- - -New checks: - -* Add W504 warning for checking that a break doesn't happen after a binary - operator. This check is ignored by default. PR #502. -* Add W605 warning for invalid escape sequences in string literals. PR #676. -* Add W606 warning for 'async' and 'await' reserved keywords being introduced - in Python 3.7. PR #684. -* Add E252 error for missing whitespace around equal sign in type annotated - function arguments with defaults values. PR #717. - -Changes: - -* An internal bisect search has replaced a linear search in order to improve - efficiency. PR #648. -* pycodestyle now uses PyPI trove classifiers in order to document supported - python versions on PyPI. PR #654. -* 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as - the former is legacy. PR #653. -* pycodestyle now handles very long lines much more efficiently for python - 3.2+. Fixes #643. PR #644. -* You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of - 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve - verbosity. PR #663. -* The distribution of pycodestyle now includes the license text in order to - comply with open source licenses which require this. PR #694. -* 'maximum_line_length' now ignores shebang ('#!') lines. PR #736. -* Add configuration option for the allowed number of blank lines. It is - implemented as a top level dictionary which can be easily overwritten. Fixes - #732. PR #733. - -Bugs: - -* Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused - by an invalid escape sequence. PR #625. -* Correctly report E501 when the first line of a docstring is too long. - Resolves #622. PR #630. -* Support variable annotation when variable start by a keyword, such as class - variable type annotations in python 3.6. PR #640. -* pycodestyle internals have been changed in order to allow 'python3 -m - cProfile' to report correct metrics. PR #647. -* Fix a spelling mistake in the description of E722. PR #697. -* 'pycodestyle --diff' now does not break if your 'gitconfig' enables - 'mnemonicprefix'. PR #706. - -2.3.1 (2017-01-31) ------------------- - -Bugs: - -* Fix regression in detection of E302 and E306; #618, #620 - -2.3.0 (2017-01-30) ------------------- - -New Checks: - -* Add E722 warning for bare ``except`` clauses -* Report E704 for async function definitions (``async def``) - -Bugs: - -* Fix another E305 false positive for variables beginning with "class" or - "def" -* Fix detection of multiple spaces between ``async`` and ``def`` -* Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for - variable annotations. - -2.2.0 (2016-11-14) ------------------- - -Announcements: - -* Added Make target to obtain proper tarball file permissions; #599 - -Bugs: - -* Fixed E305 regression caused by #400; #593 - -2.1.0 (2016-11-04) ------------------- - -Announcements: - -* Change all references to the pep8 project to say pycodestyle; #530 - -Changes: - -* Report E302 for blank lines before an "async def"; #556 -* Update our list of tested and supported Python versions which are 2.6, 2.7, - 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy. -* Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'. -* Report E741 on 'global' and 'nonlocal' statements, as well as prohibited - single-letter variables. -* Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591 -* Report E722 when bare except clause is used; #579 - -Bugs: - -* Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561 -* Require two blank lines after toplevel def, class; #536 -* Remove accidentally quadratic computation based on the number of colons. This - will make pycodestyle faster in some cases; #314 - -2.0.0 (2016-05-31) ------------------- - -Announcements: - -* Repository renamed to `pycodestyle`; Issue #466 / #481. -* Added joint Code of Conduct as member of PyCQA; #483 - -Changes: - -* Added tox test support for Python 3.5 and pypy3 -* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 -* Added W503 to the list of codes ignored by default ignore list; #498 -* Removed use of project level `.pep8` configuration file; #364 - -Bugs: - -* Fixed bug with treating `~` operator as binary; #383 / #384 -* Identify binary operators as unary; #484 / #485 - -1.7.0 (2016-01-12) ------------------- - -Announcements: - -* Repository moved to PyCQA Organization on GitHub: - https://github.com/pycqa/pep8 - -Changes: - -* Reverted the fix in #368, "options passed on command line are only ones - accepted" feature. This has many unintended consequences in pep8 and flake8 - and needs to be reworked when I have more time. -* Added support for Python 3.5. (Issue #420 & #459) -* Added support for multi-line config_file option parsing. (Issue #429) -* Improved parameter parsing. (Issues #420 & #456) - -Bugs: - -* Fixed BytesWarning on Python 3. (Issue #459) - -1.6.2 (2015-02-15) ------------------- - -Changes: - -* Added check for breaking around a binary operator. (Issue #197, Pull #305) - -Bugs: - -* Restored config_file parameter in process_options(). (Issue #380) - - -1.6.1 (2015-02-08) ------------------- - -Changes: - -* Assign variables before referenced. (Issue #287) - -Bugs: - -* Exception thrown due to unassigned ``local_dir`` variable. (Issue #377) - - -1.6.0 (2015-02-06) ------------------- - -News: - -* Ian Lee joined the project as a maintainer. - -Changes: - -* Report E731 for lambda assignment. (Issue #277) - -* Report E704 for one-liner def instead of E701. - Do not report this error in the default configuration. (Issue #277) - -* Replace codes E111, E112 and E113 with codes E114, E115 and E116 - for bad indentation of comments. (Issue #274) - -* Report E266 instead of E265 when the block comment starts with - multiple ``#``. (Issue #270) - -* Report E402 for import statements not at the top of the file. (Issue #264) - -* Do not enforce whitespaces around ``**`` operator. (Issue #292) - -* Strip whitespace from around paths during normalization. (Issue #339 / #343) - -* Update ``--format`` documentation. (Issue #198 / Pull Request #310) - -* Add ``.tox/`` to default excludes. (Issue #335) - -* Do not report E121 or E126 in the default configuration. (Issues #256 / #316) - -* Allow spaces around the equals sign in an annotated function. (Issue #357) - -* Allow trailing backslash if in an inline comment. (Issue #374) - -* If ``--config`` is used, only that configuration is processed. Otherwise, - merge the user and local configurations are merged. (Issue #368 / #369) - -Bug fixes: - -* Don't crash if Checker.build_tokens_line() returns None. (Issue #306) - -* Don't crash if os.path.expanduser() throws an ImportError. (Issue #297) - -* Missing space around keyword parameter equal not always reported, E251. - (Issue #323) - -* Fix false positive E711/E712/E713. (Issues #330 and #336) - -* Do not skip physical checks if the newline is escaped. (Issue #319) - -* Flush sys.stdout to avoid race conditions with printing. See flake8 bug: - https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363) - - -1.5.7 (2014-05-29) ------------------- - -Bug fixes: - -* Skip the traceback on "Broken pipe" signal. (Issue #275) - -* Do not exit when an option in ``setup.cfg`` or ``tox.ini`` - is not recognized. - -* Check the last line even if it does not end with a newline. (Issue #286) - -* Always open files in universal newlines mode in Python 2. (Issue #288) - - -1.5.6 (2014-04-14) ------------------- - -Bug fixes: - -* Check the last line even if it has no end-of-line. (Issue #273) - - -1.5.5 (2014-04-10) ------------------- - -Bug fixes: - -* Fix regression with E22 checks and inline comments. (Issue #271) - - -1.5.4 (2014-04-07) ------------------- - -Bug fixes: - -* Fix negative offset with E303 before a multi-line docstring. - (Issue #269) - - -1.5.3 (2014-04-04) ------------------- - -Bug fixes: - -* Fix wrong offset computation when error is on the last char - of a physical line. (Issue #268) - - -1.5.2 (2014-04-04) ------------------- - -Changes: - -* Distribute a universal wheel file. - -Bug fixes: - -* Report correct line number for E303 with comments. (Issue #60) - -* Do not allow newline after parameter equal. (Issue #252) - -* Fix line number reported for multi-line strings. (Issue #220) - -* Fix false positive E121/E126 with multi-line strings. (Issue #265) - -* Fix E501 not detected in comments with Python 2.5. - -* Fix caret position with ``--show-source`` when line contains tabs. - - -1.5.1 (2014-03-27) ------------------- - -Bug fixes: - -* Fix a crash with E125 on multi-line strings. (Issue #263) - - -1.5 (2014-03-26) ----------------- - -Changes: - -* Report E129 instead of E125 for visually indented line with same - indent as next logical line. (Issue #126) - -* Report E265 for space before block comment. (Issue #190) - -* Report E713 and E714 when operators ``not in`` and ``is not`` are - recommended. (Issue #236) - -* Allow long lines in multiline strings and comments if they cannot - be wrapped. (Issue #224). - -* Optionally disable physical line checks inside multiline strings, - using ``# noqa``. (Issue #242) - -* Change text for E121 to report "continuation line under-indented - for hanging indent" instead of indentation not being a - multiple of 4. - -* Report E131 instead of E121 / E126 if the hanging indent is not - consistent within the same continuation block. It helps when - error E121 or E126 is in the ``ignore`` list. - -* Report E126 instead of E121 when the continuation line is hanging - with extra indentation, even if indentation is not a multiple of 4. - -Bug fixes: - -* Allow the checkers to report errors on empty files. (Issue #240) - -* Fix ignoring too many checks when ``--select`` is used with codes - declared in a flake8 extension. (Issue #216) - -* Fix regression with multiple brackets. (Issue #214) - -* Fix ``StyleGuide`` to parse the local configuration if the - keyword argument ``paths`` is specified. (Issue #246) - -* Fix a false positive E124 for hanging indent. (Issue #254) - -* Fix a false positive E126 with embedded colon. (Issue #144) - -* Fix a false positive E126 when indenting with tabs. (Issue #204) - -* Fix behaviour when ``exclude`` is in the configuration file and - the current directory is not the project directory. (Issue #247) - -* The logical checks can return ``None`` instead of an empty iterator. - (Issue #250) - -* Do not report multiple E101 if only the first indentation starts - with a tab. (Issue #237) - -* Fix a rare false positive W602. (Issue #34) - - -1.4.6 (2013-07-02) ------------------- - -Changes: - -* Honor ``# noqa`` for errors E711 and E712. (Issue #180) - -* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project - directory, merge their contents. The ``tox.ini`` file takes - precedence (same as before). (Issue #182) - -* Give priority to ``--select`` over ``--ignore``. (Issue #188) - -* Compare full path when excluding a file. (Issue #186) - -* New option ``--hang-closing`` to switch to the alternative style of - closing bracket indentation for hanging indent. Add error E133 for - closing bracket which is missing indentation. (Issue #103) - -* Accept both styles of closing bracket indentation for hanging indent. - Do not report error E123 in the default configuration. (Issue #103) - -Bug fixes: - -* Do not crash when running AST checks and the document contains null bytes. - (Issue #184) - -* Correctly report other E12 errors when E123 is ignored. (Issue #103) - -* Fix false positive E261/E262 when the file contains a BOM. (Issue #193) - -* Fix E701, E702 and E703 not detected sometimes. (Issue #196) - -* Fix E122 not detected in some cases. (Issue #201 and #208) - -* Fix false positive E121 with multiple brackets. (Issue #203) - - -1.4.5 (2013-03-06) ------------------- - -* When no path is specified, do not try to read from stdin. The feature - was added in 1.4.3, but it is not supported on Windows. Use ``-`` - filename argument to read from stdin. This usage is supported - since 1.3.4. (Issue #170) - -* Do not require ``setuptools`` in setup.py. It works around an issue - with ``pip`` and Python 3. (Issue #172) - -* Add ``__pycache__`` to the ignore list. - -* Change misleading message for E251. (Issue #171) - -* Do not report false E302 when the source file has a coding cookie or a - comment on the first line. (Issue #174) - -* Reorganize the tests and add tests for the API and for the command line - usage and options. (Issues #161 and #162) - -* Ignore all checks which are not explicitly selected when ``select`` is - passed to the ``StyleGuide`` constructor. - - -1.4.4 (2013-02-24) ------------------- - -* Report E227 or E228 instead of E225 for whitespace around bitwise, shift - or modulo operators. (Issue #166) - -* Change the message for E226 to make clear that it is about arithmetic - operators. - -* Fix a false positive E128 for continuation line indentation with tabs. - -* Fix regression with the ``--diff`` option. (Issue #169) - -* Fix the ``TestReport`` class to print the unexpected warnings and - errors. - - -1.4.3 (2013-02-22) ------------------- - -* Hide the ``--doctest`` and ``--testsuite`` options when installed. - -* Fix crash with AST checkers when the syntax is invalid. (Issue #160) - -* Read from standard input if no path is specified. - -* Initiate a graceful shutdown on ``Control+C``. - -* Allow changing the ``checker_class`` for the ``StyleGuide``. - - -1.4.2 (2013-02-10) ------------------- - -* Support AST checkers provided by third-party applications. - -* Register new checkers with ``register_check(func_or_cls, codes)``. - -* Allow constructing a ``StyleGuide`` with a custom parser. - -* Accept visual indentation without parenthesis after the ``if`` - statement. (Issue #151) - -* Fix UnboundLocalError when using ``# noqa`` with continued lines. - (Issue #158) - -* Re-order the lines for the ``StandardReport``. - -* Expand tabs when checking E12 continuation lines. (Issue #155) - -* Refactor the testing class ``TestReport`` and the specific test - functions into a separate test module. - - -1.4.1 (2013-01-18) ------------------- - -* Allow sphinx.ext.autodoc syntax for comments. (Issue #110) - -* Report E703 instead of E702 for the trailing semicolon. (Issue #117) - -* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149) - -* Expose the ``OptionParser`` factory for better extensibility. - - -1.4 (2012-12-22) ----------------- - -* Report E226 instead of E225 for optional whitespace around common - operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error - code is ignored in the default configuration because PEP 8 recommends - to "use your own judgement". (Issue #96) - -* Lines with a ``# nopep8`` at the end will not issue errors on line - length E501 or continuation line indentation E12*. (Issue #27) - -* Fix AssertionError when the source file contains an invalid line - ending ``"\r\r\n"``. (Issue #119) - -* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present. - (Issue #93 and #141) - -* Add the Sphinx-based documentation, and publish it - on https://pycodestyle.readthedocs.io/. (Issue #105) - - -1.3.4 (2012-12-18) ------------------- - -* Fix false positive E124 and E128 with comments. (Issue #100) - -* Fix error on stdin when running with bpython. (Issue #101) - -* Fix false positive E401. (Issue #104) - -* Report E231 for nested dictionary in list. (Issue #142) - -* Catch E271 at the beginning of the line. (Issue #133) - -* Fix false positive E126 for multi-line comments. (Issue #138) - -* Fix false positive E221 when operator is preceded by a comma. (Issue #135) - -* Fix ``--diff`` failing on one-line hunk. (Issue #137) - -* Fix the ``--exclude`` switch for directory paths. (Issue #111) - -* Use ``-`` filename to read from standard input. (Issue #128) - - -1.3.3 (2012-06-27) ------------------- - -* Fix regression with continuation line checker. (Issue #98) - - -1.3.2 (2012-06-26) ------------------- - -* Revert to the previous behaviour for ``--show-pep8``: - do not imply ``--first``. (Issue #89) - -* Add E902 for IO errors. (Issue #87) - -* Fix false positive for E121, and missed E124. (Issue #92) - -* Set a sensible default path for config file on Windows. (Issue #95) - -* Allow ``verbose`` in the configuration file. (Issue #91) - -* Show the enforced ``max-line-length`` in the error message. (Issue #86) - - -1.3.1 (2012-06-18) ------------------- - -* Explain which configuration options are expected. Accept and recommend - the options names with hyphen instead of underscore. (Issue #82) - -* Do not read the user configuration when used as a module - (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor). - -* Fix wrong or missing cases for the E12 series. - -* Fix cases where E122 was missed. (Issue #81) - - -1.3 (2012-06-15) ----------------- - -.. warning:: - The internal API is backwards incompatible. - -* Remove global configuration and refactor the library around - a ``StyleGuide`` class; add the ability to configure various - reporters. (Issue #35 and #66) - -* Read user configuration from ``~/.config/pep8`` - and local configuration from ``./.pep8``. (Issue #22) - -* Fix E502 for backslash embedded in multi-line string. (Issue #68) - -* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72) - -* Enable the new checkers from the E12 series in the default - configuration. - -* Suggest less error-prone alternatives for E712 errors. - -* Rewrite checkers to run faster (E22, E251, E27). - -* Fixed a crash when parsed code is invalid (too many - closing brackets). - -* Fix E127 and E128 for continuation line indentation. (Issue #74) - -* New option ``--format`` to customize the error format. (Issue #23) - -* New option ``--diff`` to check only modified code. The unified - diff is read from STDIN. Example: ``hg diff | pep8 --diff`` - (Issue #39) - -* Correctly report the count of failures and set the exit code to 1 - when the ``--doctest`` or the ``--testsuite`` fails. - -* Correctly detect the encoding in Python 3. (Issue #69) - -* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78) - - -1.2 (2012-06-01) ----------------- - -* Add E121 through E128 for continuation line indentation. These - checks are disabled by default. If you want to force all checks, - use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64) - -* Add E721 for direct type comparisons. (Issue #47) - -* Add E711 and E712 for comparisons to singletons. (Issue #46) - -* Fix spurious E225 and E701 for function annotations. (Issue #29) - -* Add E502 for explicit line join between brackets. - -* Fix E901 when printing source with ``--show-source``. - -* Report all errors for each checker, instead of reporting only the - first occurrence for each line. - -* Option ``--show-pep8`` implies ``--first``. - - -1.1 (2012-05-24) ----------------- - -* Add E901 for syntax errors. (Issues #63 and #30) - -* Add E271, E272, E273 and E274 for extraneous whitespace around - keywords. (Issue #57) - -* Add ``tox.ini`` configuration file for tests. (Issue #61) - -* Add ``.travis.yml`` configuration file for continuous integration. - (Issue #62) - - -1.0.1 (2012-04-06) ------------------- - -* Fix inconsistent version numbers. - - -1.0 (2012-04-04) ----------------- - -* Fix W602 ``raise`` to handle multi-char names. (Issue #53) - - -0.7.0 (2012-03-26) ------------------- - -* Now ``--first`` prints only the first occurrence of each error. - The ``--repeat`` flag becomes obsolete because it is the default - behaviour. (Issue #6) - -* Allow specifying ``--max-line-length``. (Issue #36) - -* Make the shebang more flexible. (Issue #26) - -* Add testsuite to the bundle. (Issue #25) - -* Fixes for Jython. (Issue #49) - -* Add PyPI classifiers. (Issue #43) - -* Fix the ``--exclude`` option. (Issue #48) - -* Fix W602, accept ``raise`` with 3 arguments. (Issue #34) - -* Correctly select all tests if ``DEFAULT_IGNORE == ''``. - - -0.6.1 (2010-10-03) ------------------- - -* Fix inconsistent version numbers. (Issue #21) - - -0.6.0 (2010-09-19) ------------------- - -* Test suite reorganized and enhanced in order to check more failures - with fewer test files. Read the ``run_tests`` docstring for details - about the syntax. - -* Fix E225: accept ``print >>sys.stderr, "..."`` syntax. - -* Fix E501 for lines containing multibyte encoded characters. (Issue #7) - -* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16) - -* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17) - -* Exit code is always 1 if any error or warning is found. (Issue #10) - -* ``--ignore`` checks are now really ignored, especially in - conjunction with ``--count``. (Issue #8) - -* Blank lines with spaces yield W293 instead of W291: some developers - want to ignore this warning and indent the blank lines to paste their - code easily in the Python interpreter. - -* Fix E301: do not require a blank line before an indented block. (Issue #14) - -* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13) - -* Performance improvements. - -* Fix decoding and checking non-UTF8 files in Python 3. - -* Fix E225: reject ``True+False`` when running on Python 3. - -* Fix an exception when the line starts with an operator. - -* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5) - - -0.5.0 (2010-02-17) ------------------- - -* Changed the ``--count`` switch to print to sys.stderr and set - exit code to 1 if any error or warning is found. - -* E241 and E242 are removed from the standard checks. If you want to - include these checks, use switch ``--select=E,W``. (Issue #4) - -* Blank line is not mandatory before the first class method or nested - function definition, even if there's a docstring. (Issue #1) - -* Add the switch ``--version``. - -* Fix decoding errors with Python 3. (Issue #13 [1]_) - -* Add ``--select`` option which is mirror of ``--ignore``. - -* Add checks E261 and E262 for spaces before inline comments. - -* New check W604 warns about deprecated usage of backticks. - -* New check W603 warns about the deprecated operator ``<>``. - -* Performance improvement, due to rewriting of E225. - -* E225 now accepts: - - - no whitespace after unary operator or similar. (Issue #9 [1]_) - - - lambda function with argument unpacking or keyword defaults. - -* Reserve "2 blank lines" for module-level logical blocks. (E303) - -* Allow multi-line comments. (E302, issue #10 [1]_) - - -0.4.2 (2009-10-22) ------------------- - -* Decorators on classes and class methods are OK now. - - -0.4 (2009-10-20) ----------------- - -* Support for all versions of Python from 2.3 to 3.1. - -* New and greatly expanded self tests. - -* Added ``--count`` option to print the total number of errors and warnings. - -* Further improvements to the handling of comments and blank lines. - (Issue #1 [1]_ and others changes.) - -* Check all py files in directory when passed a directory (Issue - #2 [1]_). This also prevents an exception when traversing directories - with non ``*.py`` files. - -* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_) - -* Spaces are no longer required around the equals sign for keyword - arguments or default parameter values. - - -.. [1] These issues refer to the `previous issue tracker`__. -.. __: http://github.com/cburroughs/pep8.py/issues - - -0.3.1 (2009-09-14) ------------------- - -* Fixes for comments: do not count them when checking for blank lines between - items. - -* Added setup.py for pypi upload and easy_installability. - - -0.2 (2007-10-16) ----------------- - -* Loads of fixes and improvements. - - -0.1 (2006-10-01) ----------------- - -* First release. - - diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/RECORD b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/RECORD deleted file mode 100644 index 871387cc..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/RECORD +++ /dev/null @@ -1,11 +0,0 @@ -../../../bin/pycodestyle,sha256=zpOaxdWzTqgaTokbUWK1xsOsL2WbPK4WmyovSlDBqEk,257 -__pycache__/pycodestyle.cpython-38.pyc,, -pycodestyle-2.6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pycodestyle-2.6.0.dist-info/LICENSE,sha256=93IpXoGvNHjTTojlLQdiACMOx91qOeEjvFyzWqZqva4,1254 -pycodestyle-2.6.0.dist-info/METADATA,sha256=WI4-bMnR66kT7MKGLVFW7xqmuotPGP0uLJProv7nhD4,30287 -pycodestyle-2.6.0.dist-info/RECORD,, -pycodestyle-2.6.0.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -pycodestyle-2.6.0.dist-info/entry_points.txt,sha256=6JU_7SAppC93MBSQi1_QxDwEQUyg6cgK71ab9q_Hxco,51 -pycodestyle-2.6.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 -pycodestyle-2.6.0.dist-info/top_level.txt,sha256=rHbIEiXmvsJ016mFcLVcF_d-dKgP3VdfOB6CWbivZug,12 -pycodestyle.py,sha256=xYcAkNSMHMAlz6cmdkfhwK7QC5RsRwK2pfG2_uPI2xM,103376 diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/WHEEL b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/WHEEL deleted file mode 100644 index ef99c6cf..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/entry_points.txt deleted file mode 100644 index 71bd8850..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -pycodestyle = pycodestyle:_main - diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/namespace_packages.txt b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/namespace_packages.txt deleted file mode 100644 index 8b137891..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/namespace_packages.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/top_level.txt b/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/top_level.txt deleted file mode 100644 index 282a93fb..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle-2.6.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pycodestyle diff --git a/env/lib/python3.8/site-packages/pycodestyle.py b/env/lib/python3.8/site-packages/pycodestyle.py deleted file mode 100644 index deb45395..00000000 --- a/env/lib/python3.8/site-packages/pycodestyle.py +++ /dev/null @@ -1,2763 +0,0 @@ -#!/usr/bin/env python -# pycodestyle.py - Check Python source code formatting, according to -# PEP 8 -# -# Copyright (C) 2006-2009 Johann C. Rocholl -# Copyright (C) 2009-2014 Florent Xicluna -# Copyright (C) 2014-2016 Ian Lee -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -r""" -Check Python source code formatting, according to PEP 8. - -For usage and a list of options, try this: -$ python pycodestyle.py -h - -This program and its regression test suite live here: -https://github.com/pycqa/pycodestyle - -Groups of errors and warnings: -E errors -W warnings -100 indentation -200 whitespace -300 blank lines -400 imports -500 line length -600 deprecation -700 statements -900 syntax error -""" -from __future__ import with_statement - -import inspect -import keyword -import os -import re -import sys -import time -import tokenize -import warnings -import bisect - -try: - from functools import lru_cache -except ImportError: - def lru_cache(maxsize=128): # noqa as it's a fake implementation. - """Does not really need a real a lru_cache, it's just - optimization, so let's just do nothing here. Python 3.2+ will - just get better performances, time to upgrade? - """ - return lambda function: function - -from fnmatch import fnmatch -from optparse import OptionParser - -try: - from configparser import RawConfigParser - from io import TextIOWrapper -except ImportError: - from ConfigParser import RawConfigParser - -__version__ = '2.6.0' - -DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' -DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' -try: - if sys.platform == 'win32': - USER_CONFIG = os.path.expanduser(r'~\.pycodestyle') - else: - USER_CONFIG = os.path.join( - os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), - 'pycodestyle' - ) -except ImportError: - USER_CONFIG = None - -PROJECT_CONFIG = ('setup.cfg', 'tox.ini') -TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite') -MAX_LINE_LENGTH = 79 -# Number of blank lines between various code parts. -BLANK_LINES_CONFIG = { - # Top level class and function. - 'top_level': 2, - # Methods and nested class and function. - 'method': 1, -} -MAX_DOC_LENGTH = 72 -REPORT_FORMAT = { - 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', - 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', -} - -PyCF_ONLY_AST = 1024 -SINGLETONS = frozenset(['False', 'None', 'True']) -KEYWORDS = frozenset(keyword.kwlist + ['print', 'async']) - SINGLETONS -UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) -ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-', '@']) -WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) -# Warn for -> function annotation operator in py3.5+ (issue 803) -FUNCTION_RETURN_ANNOTATION_OP = ['->'] if sys.version_info >= (3, 5) else [] -ASSIGNMENT_EXPRESSION_OP = [':='] if sys.version_info >= (3, 8) else [] -WS_NEEDED_OPERATORS = frozenset([ - '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>', - '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=', - 'and', 'in', 'is', 'or'] + - FUNCTION_RETURN_ANNOTATION_OP + - ASSIGNMENT_EXPRESSION_OP) -WHITESPACE = frozenset(' \t') -NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) -SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) -# ERRORTOKEN is triggered by backticks in Python 3 -SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) -BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] - -INDENT_REGEX = re.compile(r'([ \t]*)') -RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,') -RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$') -ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') -DOCSTRING_REGEX = re.compile(r'u?r?["\']') -EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[\[({] | [\]}),;]| :(?!=)') -WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') -COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)' - r'\s*(?(1)|(None|False|True))\b') -COMPARE_NEGATIVE_REGEX = re.compile(r'\b(?%&^]+)(\s*)') -LAMBDA_REGEX = re.compile(r'\blambda\b') -HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') -STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\b') -STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)') -STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( - r'^\s*({0})\b'.format('|'.join(s.replace(' ', r'\s+') for s in ( - 'def', 'async def', - 'for', 'async for', - 'if', 'elif', 'else', - 'try', 'except', 'finally', - 'with', 'async with', - 'class', - 'while', - ))) -) -DUNDER_REGEX = re.compile(r'^__([^\s]+)__ = ') - -_checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} - - -def _get_parameters(function): - if sys.version_info >= (3, 3): - return [parameter.name - for parameter - in inspect.signature(function).parameters.values() - if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] - else: - return inspect.getargspec(function)[0] - - -def register_check(check, codes=None): - """Register a new check object.""" - def _add_check(check, kind, codes, args): - if check in _checks[kind]: - _checks[kind][check][0].extend(codes or []) - else: - _checks[kind][check] = (codes or [''], args) - if inspect.isfunction(check): - args = _get_parameters(check) - if args and args[0] in ('physical_line', 'logical_line'): - if codes is None: - codes = ERRORCODE_REGEX.findall(check.__doc__ or '') - _add_check(check, args[0], codes, args) - elif inspect.isclass(check): - if _get_parameters(check.__init__)[:2] == ['self', 'tree']: - _add_check(check, 'tree', codes, None) - return check - - -######################################################################## -# Plugins (check functions) for physical lines -######################################################################## - -@register_check -def tabs_or_spaces(physical_line, indent_char): - r"""Never mix tabs and spaces. - - The most popular way of indenting Python is with spaces only. The - second-most popular way is with tabs only. Code indented with a - mixture of tabs and spaces should be converted to using spaces - exclusively. When invoking the Python command line interpreter with - the -t option, it issues warnings about code that illegally mixes - tabs and spaces. When using -tt these warnings become errors. - These options are highly recommended! - - Okay: if a == 0:\n a = 1\n b = 1 - E101: if a == 0:\n a = 1\n\tb = 1 - """ - indent = INDENT_REGEX.match(physical_line).group(1) - for offset, char in enumerate(indent): - if char != indent_char: - return offset, "E101 indentation contains mixed spaces and tabs" - - -@register_check -def tabs_obsolete(physical_line): - r"""On new projects, spaces-only are strongly recommended over tabs. - - Okay: if True:\n return - W191: if True:\n\treturn - """ - indent = INDENT_REGEX.match(physical_line).group(1) - if '\t' in indent: - return indent.index('\t'), "W191 indentation contains tabs" - - -@register_check -def trailing_whitespace(physical_line): - r"""Trailing whitespace is superfluous. - - The warning returned varies on whether the line itself is blank, - for easier filtering for those who want to indent their blank lines. - - Okay: spam(1)\n# - W291: spam(1) \n# - W293: class Foo(object):\n \n bang = 12 - """ - physical_line = physical_line.rstrip('\n') # chr(10), newline - physical_line = physical_line.rstrip('\r') # chr(13), carriage return - physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L - stripped = physical_line.rstrip(' \t\v') - if physical_line != stripped: - if stripped: - return len(stripped), "W291 trailing whitespace" - else: - return 0, "W293 blank line contains whitespace" - - -@register_check -def trailing_blank_lines(physical_line, lines, line_number, total_lines): - r"""Trailing blank lines are superfluous. - - Okay: spam(1) - W391: spam(1)\n - - However the last line should end with a new line (warning W292). - """ - if line_number == total_lines: - stripped_last_line = physical_line.rstrip() - if physical_line and not stripped_last_line: - return 0, "W391 blank line at end of file" - if stripped_last_line == physical_line: - return len(lines[-1]), "W292 no newline at end of file" - - -@register_check -def maximum_line_length(physical_line, max_line_length, multiline, - line_number, noqa): - r"""Limit all lines to a maximum of 79 characters. - - There are still many devices around that are limited to 80 character - lines; plus, limiting windows to 80 characters makes it possible to - have several windows side-by-side. The default wrapping on such - devices looks ugly. Therefore, please limit all lines to a maximum - of 79 characters. For flowing long blocks of text (docstrings or - comments), limiting the length to 72 characters is recommended. - - Reports error E501. - """ - line = physical_line.rstrip() - length = len(line) - if length > max_line_length and not noqa: - # Special case: ignore long shebang lines. - if line_number == 1 and line.startswith('#!'): - return - # Special case for long URLs in multi-line docstrings or - # comments, but still report the error when the 72 first chars - # are whitespaces. - chunks = line.split() - if ((len(chunks) == 1 and multiline) or - (len(chunks) == 2 and chunks[0] == '#')) and \ - len(line) - len(chunks[-1]) < max_line_length - 7: - return - if hasattr(line, 'decode'): # Python 2 - # The line could contain multi-byte characters - try: - length = len(line.decode('utf-8')) - except UnicodeError: - pass - if length > max_line_length: - return (max_line_length, "E501 line too long " - "(%d > %d characters)" % (length, max_line_length)) - - -######################################################################## -# Plugins (check functions) for logical lines -######################################################################## - - -def _is_one_liner(logical_line, indent_level, lines, line_number): - if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): - return False - - line_idx = line_number - 1 - - if line_idx < 1: - prev_indent = 0 - else: - prev_indent = expand_indent(lines[line_idx - 1]) - - if prev_indent > indent_level: - return False - - while line_idx < len(lines): - line = lines[line_idx].strip() - if not line.startswith('@') and STARTSWITH_TOP_LEVEL_REGEX.match(line): - break - else: - line_idx += 1 - else: - return False # invalid syntax: EOF while searching for def/class - - next_idx = line_idx + 1 - while next_idx < len(lines): - if lines[next_idx].strip(): - break - else: - next_idx += 1 - else: - return True # line is last in the file - - return expand_indent(lines[next_idx]) <= indent_level - - -@register_check -def blank_lines(logical_line, blank_lines, indent_level, line_number, - blank_before, previous_logical, - previous_unindented_logical_line, previous_indent_level, - lines): - r"""Separate top-level function and class definitions with two blank - lines. - - Method definitions inside a class are separated by a single blank - line. - - Extra blank lines may be used (sparingly) to separate groups of - related functions. Blank lines may be omitted between a bunch of - related one-liners (e.g. a set of dummy implementations). - - Use blank lines in functions, sparingly, to indicate logical - sections. - - Okay: def a():\n pass\n\n\ndef b():\n pass - Okay: def a():\n pass\n\n\nasync def b():\n pass - Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass - Okay: default = 1\nfoo = 1 - Okay: classify = 1\nfoo = 1 - - E301: class Foo:\n b = 0\n def bar():\n pass - E302: def a():\n pass\n\ndef b(n):\n pass - E302: def a():\n pass\n\nasync def b(n):\n pass - E303: def a():\n pass\n\n\n\ndef b(n):\n pass - E303: def a():\n\n\n\n pass - E304: @decorator\n\ndef a():\n pass - E305: def a():\n pass\na() - E306: def a():\n def b():\n pass\n def c():\n pass - """ # noqa - top_level_lines = BLANK_LINES_CONFIG['top_level'] - method_lines = BLANK_LINES_CONFIG['method'] - - if not previous_logical and blank_before < top_level_lines: - return # Don't expect blank lines before the first line - if previous_logical.startswith('@'): - if blank_lines: - yield 0, "E304 blank lines found after function decorator" - elif (blank_lines > top_level_lines or - (indent_level and blank_lines == method_lines + 1) - ): - yield 0, "E303 too many blank lines (%d)" % blank_lines - elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): - # allow a group of one-liners - if ( - _is_one_liner(logical_line, indent_level, lines, line_number) and - blank_before == 0 - ): - return - if indent_level: - if not (blank_before == method_lines or - previous_indent_level < indent_level or - DOCSTRING_REGEX.match(previous_logical) - ): - ancestor_level = indent_level - nested = False - # Search backwards for a def ancestor or tree root - # (top level). - for line in lines[line_number - top_level_lines::-1]: - if line.strip() and expand_indent(line) < ancestor_level: - ancestor_level = expand_indent(line) - nested = STARTSWITH_DEF_REGEX.match(line.lstrip()) - if nested or ancestor_level == 0: - break - if nested: - yield 0, "E306 expected %s blank line before a " \ - "nested definition, found 0" % (method_lines,) - else: - yield 0, "E301 expected %s blank line, found 0" % ( - method_lines,) - elif blank_before != top_level_lines: - yield 0, "E302 expected %s blank lines, found %d" % ( - top_level_lines, blank_before) - elif (logical_line and - not indent_level and - blank_before != top_level_lines and - previous_unindented_logical_line.startswith(('def ', 'class ')) - ): - yield 0, "E305 expected %s blank lines after " \ - "class or function definition, found %d" % ( - top_level_lines, blank_before) - - -@register_check -def extraneous_whitespace(logical_line): - r"""Avoid extraneous whitespace. - - Avoid extraneous whitespace in these situations: - - Immediately inside parentheses, brackets or braces. - - Immediately before a comma, semicolon, or colon. - - Okay: spam(ham[1], {eggs: 2}) - E201: spam( ham[1], {eggs: 2}) - E201: spam(ham[ 1], {eggs: 2}) - E201: spam(ham[1], { eggs: 2}) - E202: spam(ham[1], {eggs: 2} ) - E202: spam(ham[1 ], {eggs: 2}) - E202: spam(ham[1], {eggs: 2 }) - - E203: if x == 4: print x, y; x, y = y , x - E203: if x == 4: print x, y ; x, y = y, x - E203: if x == 4 : print x, y; x, y = y, x - """ - line = logical_line - for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): - text = match.group() - char = text.strip() - found = match.start() - if text == char + ' ': - # assert char in '([{' - yield found + 1, "E201 whitespace after '%s'" % char - elif line[found - 1] != ',': - code = ('E202' if char in '}])' else 'E203') # if char in ',;:' - yield found, "%s whitespace before '%s'" % (code, char) - - -@register_check -def whitespace_around_keywords(logical_line): - r"""Avoid extraneous whitespace around keywords. - - Okay: True and False - E271: True and False - E272: True and False - E273: True and\tFalse - E274: True\tand False - """ - for match in KEYWORD_REGEX.finditer(logical_line): - before, after = match.groups() - - if '\t' in before: - yield match.start(1), "E274 tab before keyword" - elif len(before) > 1: - yield match.start(1), "E272 multiple spaces before keyword" - - if '\t' in after: - yield match.start(2), "E273 tab after keyword" - elif len(after) > 1: - yield match.start(2), "E271 multiple spaces after keyword" - - -@register_check -def missing_whitespace_after_import_keyword(logical_line): - r"""Multiple imports in form from x import (a, b, c) should have - space between import statement and parenthesised name list. - - Okay: from foo import (bar, baz) - E275: from foo import(bar, baz) - E275: from importable.module import(bar, baz) - """ - line = logical_line - indicator = ' import(' - if line.startswith('from '): - found = line.find(indicator) - if -1 < found: - pos = found + len(indicator) - 1 - yield pos, "E275 missing whitespace after keyword" - - -@register_check -def missing_whitespace(logical_line): - r"""Each comma, semicolon or colon should be followed by whitespace. - - Okay: [a, b] - Okay: (3,) - Okay: a[1:4] - Okay: a[:4] - Okay: a[1:] - Okay: a[1:4:2] - E231: ['a','b'] - E231: foo(bar,baz) - E231: [{'a':'b'}] - """ - line = logical_line - for index in range(len(line) - 1): - char = line[index] - next_char = line[index + 1] - if char in ',;:' and next_char not in WHITESPACE: - before = line[:index] - if char == ':' and before.count('[') > before.count(']') and \ - before.rfind('{') < before.rfind('['): - continue # Slice syntax, no space required - if char == ',' and next_char == ')': - continue # Allow tuple with only one element: (3,) - if char == ':' and next_char == '=' and sys.version_info >= (3, 8): - continue # Allow assignment expression - yield index, "E231 missing whitespace after '%s'" % char - - -@register_check -def indentation(logical_line, previous_logical, indent_char, - indent_level, previous_indent_level): - r"""Use 4 spaces per indentation level. - - For really old code that you don't want to mess up, you can continue - to use 8-space tabs. - - Okay: a = 1 - Okay: if a == 0:\n a = 1 - E111: a = 1 - E114: # a = 1 - - Okay: for item in items:\n pass - E112: for item in items:\npass - E115: for item in items:\n# Hi\n pass - - Okay: a = 1\nb = 2 - E113: a = 1\n b = 2 - E116: a = 1\n # b = 2 - """ - c = 0 if logical_line else 3 - tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" - if indent_level % 4: - yield 0, tmpl % (1 + c, "indentation is not a multiple of four") - indent_expect = previous_logical.endswith(':') - if indent_expect and indent_level <= previous_indent_level: - yield 0, tmpl % (2 + c, "expected an indented block") - elif not indent_expect and indent_level > previous_indent_level: - yield 0, tmpl % (3 + c, "unexpected indentation") - - if indent_expect: - expected_indent_amount = 8 if indent_char == '\t' else 4 - expected_indent_level = previous_indent_level + expected_indent_amount - if indent_level > expected_indent_level: - yield 0, tmpl % (7, 'over-indented') - - -@register_check -def continued_indentation(logical_line, tokens, indent_level, hang_closing, - indent_char, noqa, verbose): - r"""Continuation lines indentation. - - Continuation lines should align wrapped elements either vertically - using Python's implicit line joining inside parentheses, brackets - and braces, or using a hanging indent. - - When using a hanging indent these considerations should be applied: - - there should be no arguments on the first line, and - - further indentation should be used to clearly distinguish itself - as a continuation line. - - Okay: a = (\n) - E123: a = (\n ) - - Okay: a = (\n 42) - E121: a = (\n 42) - E122: a = (\n42) - E123: a = (\n 42\n ) - E124: a = (24,\n 42\n) - E125: if (\n b):\n pass - E126: a = (\n 42) - E127: a = (24,\n 42) - E128: a = (24,\n 42) - E129: if (a or\n b):\n pass - E131: a = (\n 42\n 24) - """ - first_row = tokens[0][2][0] - nrows = 1 + tokens[-1][2][0] - first_row - if noqa or nrows == 1: - return - - # indent_next tells us whether the next block is indented; assuming - # that it is indented by 4 spaces, then we should not allow 4-space - # indents on the final continuation line; in turn, some other - # indents are allowed to have an extra 4 spaces. - indent_next = logical_line.endswith(':') - - row = depth = 0 - valid_hangs = (4,) if indent_char != '\t' else (4, 8) - # remember how many brackets were opened on each line - parens = [0] * nrows - # relative indents of physical lines - rel_indent = [0] * nrows - # for each depth, collect a list of opening rows - open_rows = [[0]] - # for each depth, memorize the hanging indentation - hangs = [None] - # visual indents - indent_chances = {} - last_indent = tokens[0][2] - visual_indent = None - last_token_multiline = False - # for each depth, memorize the visual indent column - indent = [last_indent[1]] - if verbose >= 3: - print(">>> " + tokens[0][4].rstrip()) - - for token_type, text, start, end, line in tokens: - - newline = row < start[0] - first_row - if newline: - row = start[0] - first_row - newline = not last_token_multiline and token_type not in NEWLINE - - if newline: - # this is the beginning of a continuation line. - last_indent = start - if verbose >= 3: - print("... " + line.rstrip()) - - # record the initial indent. - rel_indent[row] = expand_indent(line) - indent_level - - # identify closing bracket - close_bracket = (token_type == tokenize.OP and text in ']})') - - # is the indent relative to an opening bracket line? - for open_row in reversed(open_rows[depth]): - hang = rel_indent[row] - rel_indent[open_row] - hanging_indent = hang in valid_hangs - if hanging_indent: - break - if hangs[depth]: - hanging_indent = (hang == hangs[depth]) - # is there any chance of visual indent? - visual_indent = (not close_bracket and hang > 0 and - indent_chances.get(start[1])) - - if close_bracket and indent[depth]: - # closing bracket for visual indent - if start[1] != indent[depth]: - yield (start, "E124 closing bracket does not match " - "visual indentation") - elif close_bracket and not hang: - # closing bracket matches indentation of opening - # bracket's line - if hang_closing: - yield start, "E133 closing bracket is missing indentation" - elif indent[depth] and start[1] < indent[depth]: - if visual_indent is not True: - # visual indent is broken - yield (start, "E128 continuation line " - "under-indented for visual indent") - elif hanging_indent or (indent_next and rel_indent[row] == 8): - # hanging indent is verified - if close_bracket and not hang_closing: - yield (start, "E123 closing bracket does not match " - "indentation of opening bracket's line") - hangs[depth] = hang - elif visual_indent is True: - # visual indent is verified - indent[depth] = start[1] - elif visual_indent in (text, str): - # ignore token lined up with matching one from a - # previous line - pass - else: - # indent is broken - if hang <= 0: - error = "E122", "missing indentation or outdented" - elif indent[depth]: - error = "E127", "over-indented for visual indent" - elif not close_bracket and hangs[depth]: - error = "E131", "unaligned for hanging indent" - else: - hangs[depth] = hang - if hang > 4: - error = "E126", "over-indented for hanging indent" - else: - error = "E121", "under-indented for hanging indent" - yield start, "%s continuation line %s" % error - - # look for visual indenting - if (parens[row] and - token_type not in (tokenize.NL, tokenize.COMMENT) and - not indent[depth]): - indent[depth] = start[1] - indent_chances[start[1]] = True - if verbose >= 4: - print("bracket depth %s indent to %s" % (depth, start[1])) - # deal with implicit string concatenation - elif (token_type in (tokenize.STRING, tokenize.COMMENT) or - text in ('u', 'ur', 'b', 'br')): - indent_chances[start[1]] = str - # visual indent after assert/raise/with - elif not row and not depth and text in ["assert", "raise", "with"]: - indent_chances[end[1] + 1] = True - # special case for the "if" statement because len("if (") == 4 - elif not indent_chances and not row and not depth and text == 'if': - indent_chances[end[1] + 1] = True - elif text == ':' and line[end[1]:].isspace(): - open_rows[depth].append(row) - - # keep track of bracket depth - if token_type == tokenize.OP: - if text in '([{': - depth += 1 - indent.append(0) - hangs.append(None) - if len(open_rows) == depth: - open_rows.append([]) - open_rows[depth].append(row) - parens[row] += 1 - if verbose >= 4: - print("bracket depth %s seen, col %s, visual min = %s" % - (depth, start[1], indent[depth])) - elif text in ')]}' and depth > 0: - # parent indents should not be more than this one - prev_indent = indent.pop() or last_indent[1] - hangs.pop() - for d in range(depth): - if indent[d] > prev_indent: - indent[d] = 0 - for ind in list(indent_chances): - if ind >= prev_indent: - del indent_chances[ind] - del open_rows[depth + 1:] - depth -= 1 - if depth: - indent_chances[indent[depth]] = True - for idx in range(row, -1, -1): - if parens[idx]: - parens[idx] -= 1 - break - assert len(indent) == depth + 1 - if start[1] not in indent_chances: - # allow lining up tokens - indent_chances[start[1]] = text - - last_token_multiline = (start[0] != end[0]) - if last_token_multiline: - rel_indent[end[0] - first_row] = rel_indent[row] - - if indent_next and expand_indent(line) == indent_level + 4: - pos = (start[0], indent[0] + 4) - if visual_indent: - code = "E129 visually indented line" - else: - code = "E125 continuation line" - yield pos, "%s with same indent as next logical line" % code - - -@register_check -def whitespace_before_parameters(logical_line, tokens): - r"""Avoid extraneous whitespace. - - Avoid extraneous whitespace in the following situations: - - before the open parenthesis that starts the argument list of a - function call. - - before the open parenthesis that starts an indexing or slicing. - - Okay: spam(1) - E211: spam (1) - - Okay: dict['key'] = list[index] - E211: dict ['key'] = list[index] - E211: dict['key'] = list [index] - """ - prev_type, prev_text, __, prev_end, __ = tokens[0] - for index in range(1, len(tokens)): - token_type, text, start, end, __ = tokens[index] - if (token_type == tokenize.OP and - text in '([' and - start != prev_end and - (prev_type == tokenize.NAME or prev_text in '}])') and - # Syntax "class A (B):" is allowed, but avoid it - (index < 2 or tokens[index - 2][1] != 'class') and - # Allow "return (a.foo for a in range(5))" - not keyword.iskeyword(prev_text)): - yield prev_end, "E211 whitespace before '%s'" % text - prev_type = token_type - prev_text = text - prev_end = end - - -@register_check -def whitespace_around_operator(logical_line): - r"""Avoid extraneous whitespace around an operator. - - Okay: a = 12 + 3 - E221: a = 4 + 5 - E222: a = 4 + 5 - E223: a = 4\t+ 5 - E224: a = 4 +\t5 - """ - for match in OPERATOR_REGEX.finditer(logical_line): - before, after = match.groups() - - if '\t' in before: - yield match.start(1), "E223 tab before operator" - elif len(before) > 1: - yield match.start(1), "E221 multiple spaces before operator" - - if '\t' in after: - yield match.start(2), "E224 tab after operator" - elif len(after) > 1: - yield match.start(2), "E222 multiple spaces after operator" - - -@register_check -def missing_whitespace_around_operator(logical_line, tokens): - r"""Surround operators with a single space on either side. - - - Always surround these binary operators with a single space on - either side: assignment (=), augmented assignment (+=, -= etc.), - comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), - Booleans (and, or, not). - - - If operators with different priorities are used, consider adding - whitespace around the operators with the lowest priorities. - - Okay: i = i + 1 - Okay: submitted += 1 - Okay: x = x * 2 - 1 - Okay: hypot2 = x * x + y * y - Okay: c = (a + b) * (a - b) - Okay: foo(bar, key='word', *args, **kwargs) - Okay: alpha[:-i] - - E225: i=i+1 - E225: submitted +=1 - E225: x = x /2 - 1 - E225: z = x **y - E225: z = 1and 1 - E226: c = (a+b) * (a-b) - E226: hypot2 = x*x + y*y - E227: c = a|b - E228: msg = fmt%(errno, errmsg) - """ - parens = 0 - need_space = False - prev_type = tokenize.OP - prev_text = prev_end = None - operator_types = (tokenize.OP, tokenize.NAME) - for token_type, text, start, end, line in tokens: - if token_type in SKIP_COMMENTS: - continue - if text in ('(', 'lambda'): - parens += 1 - elif text == ')': - parens -= 1 - if need_space: - if start != prev_end: - # Found a (probably) needed space - if need_space is not True and not need_space[1]: - yield (need_space[0], - "E225 missing whitespace around operator") - need_space = False - elif text == '>' and prev_text in ('<', '-'): - # Tolerate the "<>" operator, even if running Python 3 - # Deal with Python 3's annotated return value "->" - pass - elif ( - # def f(a, /, b): - # ^ - # def f(a, b, /): - # ^ - prev_text == '/' and text in {',', ')'} or - # def f(a, b, /): - # ^ - prev_text == ')' and text == ':' - ): - # Tolerate the "/" operator in function definition - # For more info see PEP570 - pass - else: - if need_space is True or need_space[1]: - # A needed trailing space was not found - yield prev_end, "E225 missing whitespace around operator" - elif prev_text != '**': - code, optype = 'E226', 'arithmetic' - if prev_text == '%': - code, optype = 'E228', 'modulo' - elif prev_text not in ARITHMETIC_OP: - code, optype = 'E227', 'bitwise or shift' - yield (need_space[0], "%s missing whitespace " - "around %s operator" % (code, optype)) - need_space = False - elif token_type in operator_types and prev_end is not None: - if text == '=' and parens: - # Allow keyword args or defaults: foo(bar=None). - pass - elif text in WS_NEEDED_OPERATORS: - need_space = True - elif text in UNARY_OPERATORS: - # Check if the operator is used as a binary operator - # Allow unary operators: -123, -x, +1. - # Allow argument unpacking: foo(*args, **kwargs). - if (prev_text in '}])' if prev_type == tokenize.OP - else prev_text not in KEYWORDS): - need_space = None - elif text in WS_OPTIONAL_OPERATORS: - need_space = None - - if need_space is None: - # Surrounding space is optional, but ensure that - # trailing space matches opening space - need_space = (prev_end, start != prev_end) - elif need_space and start == prev_end: - # A needed opening space was not found - yield prev_end, "E225 missing whitespace around operator" - need_space = False - prev_type = token_type - prev_text = text - prev_end = end - - -@register_check -def whitespace_around_comma(logical_line): - r"""Avoid extraneous whitespace after a comma or a colon. - - Note: these checks are disabled by default - - Okay: a = (1, 2) - E241: a = (1, 2) - E242: a = (1,\t2) - """ - line = logical_line - for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): - found = m.start() + 1 - if '\t' in m.group(): - yield found, "E242 tab after '%s'" % m.group()[0] - else: - yield found, "E241 multiple spaces after '%s'" % m.group()[0] - - -@register_check -def whitespace_around_named_parameter_equals(logical_line, tokens): - r"""Don't use spaces around the '=' sign in function arguments. - - Don't use spaces around the '=' sign when used to indicate a - keyword argument or a default parameter value, except when - using a type annotation. - - Okay: def complex(real, imag=0.0): - Okay: return magic(r=real, i=imag) - Okay: boolean(a == b) - Okay: boolean(a != b) - Okay: boolean(a <= b) - Okay: boolean(a >= b) - Okay: def foo(arg: int = 42): - Okay: async def foo(arg: int = 42): - - E251: def complex(real, imag = 0.0): - E251: return magic(r = real, i = imag) - E252: def complex(real, image: float=0.0): - """ - parens = 0 - no_space = False - require_space = False - prev_end = None - annotated_func_arg = False - in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line)) - - message = "E251 unexpected spaces around keyword / parameter equals" - missing_message = "E252 missing whitespace around parameter equals" - - for token_type, text, start, end, line in tokens: - if token_type == tokenize.NL: - continue - if no_space: - no_space = False - if start != prev_end: - yield (prev_end, message) - if require_space: - require_space = False - if start == prev_end: - yield (prev_end, missing_message) - if token_type == tokenize.OP: - if text in '([': - parens += 1 - elif text in ')]': - parens -= 1 - elif in_def and text == ':' and parens == 1: - annotated_func_arg = True - elif parens == 1 and text == ',': - annotated_func_arg = False - elif parens and text == '=': - if annotated_func_arg and parens == 1: - require_space = True - if start == prev_end: - yield (prev_end, missing_message) - else: - no_space = True - if start != prev_end: - yield (prev_end, message) - if not parens: - annotated_func_arg = False - - prev_end = end - - -@register_check -def whitespace_before_comment(logical_line, tokens): - r"""Separate inline comments by at least two spaces. - - An inline comment is a comment on the same line as a statement. - Inline comments should be separated by at least two spaces from the - statement. They should start with a # and a single space. - - Each line of a block comment starts with a # and a single space - (unless it is indented text inside the comment). - - Okay: x = x + 1 # Increment x - Okay: x = x + 1 # Increment x - Okay: # Block comment - E261: x = x + 1 # Increment x - E262: x = x + 1 #Increment x - E262: x = x + 1 # Increment x - E265: #Block comment - E266: ### Block comment - """ - prev_end = (0, 0) - for token_type, text, start, end, line in tokens: - if token_type == tokenize.COMMENT: - inline_comment = line[:start[1]].strip() - if inline_comment: - if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: - yield (prev_end, - "E261 at least two spaces before inline comment") - symbol, sp, comment = text.partition(' ') - bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#') - if inline_comment: - if bad_prefix or comment[:1] in WHITESPACE: - yield start, "E262 inline comment should start with '# '" - elif bad_prefix and (bad_prefix != '!' or start[0] > 1): - if bad_prefix != '#': - yield start, "E265 block comment should start with '# '" - elif comment: - yield start, "E266 too many leading '#' for block comment" - elif token_type != tokenize.NL: - prev_end = end - - -@register_check -def imports_on_separate_lines(logical_line): - r"""Place imports on separate lines. - - Okay: import os\nimport sys - E401: import sys, os - - Okay: from subprocess import Popen, PIPE - Okay: from myclas import MyClass - Okay: from foo.bar.yourclass import YourClass - Okay: import myclass - Okay: import foo.bar.yourclass - """ - line = logical_line - if line.startswith('import '): - found = line.find(',') - if -1 < found and ';' not in line[:found]: - yield found, "E401 multiple imports on one line" - - -@register_check -def module_imports_on_top_of_file( - logical_line, indent_level, checker_state, noqa): - r"""Place imports at the top of the file. - - Always put imports at the top of the file, just after any module - comments and docstrings, and before module globals and constants. - - Okay: import os - Okay: # this is a comment\nimport os - Okay: '''this is a module docstring'''\nimport os - Okay: r'''this is a module docstring'''\nimport os - Okay: - try:\n\timport x\nexcept ImportError:\n\tpass\nelse:\n\tpass\nimport y - Okay: - try:\n\timport x\nexcept ImportError:\n\tpass\nfinally:\n\tpass\nimport y - E402: a=1\nimport os - E402: 'One string'\n"Two string"\nimport os - E402: a=1\nfrom sys import x - - Okay: if x:\n import os - """ # noqa - def is_string_literal(line): - if line[0] in 'uUbB': - line = line[1:] - if line and line[0] in 'rR': - line = line[1:] - return line and (line[0] == '"' or line[0] == "'") - - allowed_keywords = ( - 'try', 'except', 'else', 'finally', 'with', 'if', 'elif') - - if indent_level: # Allow imports in conditional statement/function - return - if not logical_line: # Allow empty lines or comments - return - if noqa: - return - line = logical_line - if line.startswith('import ') or line.startswith('from '): - if checker_state.get('seen_non_imports', False): - yield 0, "E402 module level import not at top of file" - elif re.match(DUNDER_REGEX, line): - return - elif any(line.startswith(kw) for kw in allowed_keywords): - # Allow certain keywords intermixed with imports in order to - # support conditional or filtered importing - return - elif is_string_literal(line): - # The first literal is a docstring, allow it. Otherwise, report - # error. - if checker_state.get('seen_docstring', False): - checker_state['seen_non_imports'] = True - else: - checker_state['seen_docstring'] = True - else: - checker_state['seen_non_imports'] = True - - -@register_check -def compound_statements(logical_line): - r"""Compound statements (on the same line) are generally - discouraged. - - While sometimes it's okay to put an if/for/while with a small body - on the same line, never do this for multi-clause statements. - Also avoid folding such long lines! - - Always use a def statement instead of an assignment statement that - binds a lambda expression directly to a name. - - Okay: if foo == 'blah':\n do_blah_thing() - Okay: do_one() - Okay: do_two() - Okay: do_three() - - E701: if foo == 'blah': do_blah_thing() - E701: for x in lst: total += x - E701: while t < 10: t = delay() - E701: if foo == 'blah': do_blah_thing() - E701: else: do_non_blah_thing() - E701: try: something() - E701: finally: cleanup() - E701: if foo == 'blah': one(); two(); three() - E702: do_one(); do_two(); do_three() - E703: do_four(); # useless semicolon - E704: def f(x): return 2*x - E731: f = lambda x: 2*x - """ - line = logical_line - last_char = len(line) - 1 - found = line.find(':') - prev_found = 0 - counts = {char: 0 for char in '{}[]()'} - while -1 < found < last_char: - update_counts(line[prev_found:found], counts) - if ((counts['{'] <= counts['}'] and # {'a': 1} (dict) - counts['['] <= counts[']'] and # [1:2] (slice) - counts['('] <= counts[')']) and # (annotation) - not (sys.version_info >= (3, 8) and - line[found + 1] == '=')): # assignment expression - lambda_kw = LAMBDA_REGEX.search(line, 0, found) - if lambda_kw: - before = line[:lambda_kw.start()].rstrip() - if before[-1:] == '=' and isidentifier(before[:-1].strip()): - yield 0, ("E731 do not assign a lambda expression, use a " - "def") - break - if STARTSWITH_DEF_REGEX.match(line): - yield 0, "E704 multiple statements on one line (def)" - elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): - yield found, "E701 multiple statements on one line (colon)" - prev_found = found - found = line.find(':', found + 1) - found = line.find(';') - while -1 < found: - if found < last_char: - yield found, "E702 multiple statements on one line (semicolon)" - else: - yield found, "E703 statement ends with a semicolon" - found = line.find(';', found + 1) - - -@register_check -def explicit_line_join(logical_line, tokens): - r"""Avoid explicit line join between brackets. - - The preferred way of wrapping long lines is by using Python's - implied line continuation inside parentheses, brackets and braces. - Long lines can be broken over multiple lines by wrapping expressions - in parentheses. These should be used in preference to using a - backslash for line continuation. - - E502: aaa = [123, \\n 123] - E502: aaa = ("bbb " \\n "ccc") - - Okay: aaa = [123,\n 123] - Okay: aaa = ("bbb "\n "ccc") - Okay: aaa = "bbb " \\n "ccc" - Okay: aaa = 123 # \\ - """ - prev_start = prev_end = parens = 0 - comment = False - backslash = None - for token_type, text, start, end, line in tokens: - if token_type == tokenize.COMMENT: - comment = True - if start[0] != prev_start and parens and backslash and not comment: - yield backslash, "E502 the backslash is redundant between brackets" - if end[0] != prev_end: - if line.rstrip('\r\n').endswith('\\'): - backslash = (end[0], len(line.splitlines()[-1]) - 1) - else: - backslash = None - prev_start = prev_end = end[0] - else: - prev_start = start[0] - if token_type == tokenize.OP: - if text in '([{': - parens += 1 - elif text in ')]}': - parens -= 1 - - -_SYMBOLIC_OPS = frozenset("()[]{},:.;@=%~") | frozenset(("...",)) - - -def _is_binary_operator(token_type, text): - is_op_token = token_type == tokenize.OP - is_conjunction = text in ['and', 'or'] - # NOTE(sigmavirus24): Previously the not_a_symbol check was executed - # conditionally. Since it is now *always* executed, text may be - # None. In that case we get a TypeError for `text not in str`. - not_a_symbol = text and text not in _SYMBOLIC_OPS - # The % character is strictly speaking a binary operator, but the - # common usage seems to be to put it next to the format parameters, - # after a line break. - return ((is_op_token or is_conjunction) and not_a_symbol) - - -def _break_around_binary_operators(tokens): - """Private function to reduce duplication. - - This factors out the shared details between - :func:`break_before_binary_operator` and - :func:`break_after_binary_operator`. - """ - line_break = False - unary_context = True - # Previous non-newline token types and text - previous_token_type = None - previous_text = None - for token_type, text, start, end, line in tokens: - if token_type == tokenize.COMMENT: - continue - if ('\n' in text or '\r' in text) and token_type != tokenize.STRING: - line_break = True - else: - yield (token_type, text, previous_token_type, previous_text, - line_break, unary_context, start) - unary_context = text in '([{,;' - line_break = False - previous_token_type = token_type - previous_text = text - - -@register_check -def break_before_binary_operator(logical_line, tokens): - r""" - Avoid breaks before binary operators. - - The preferred place to break around a binary operator is after the - operator, not before it. - - W503: (width == 0\n + height == 0) - W503: (width == 0\n and height == 0) - W503: var = (1\n & ~2) - W503: var = (1\n / -2) - W503: var = (1\n + -1\n + -2) - - Okay: foo(\n -x) - Okay: foo(x\n []) - Okay: x = '''\n''' + '' - Okay: foo(x,\n -y) - Okay: foo(x, # comment\n -y) - """ - for context in _break_around_binary_operators(tokens): - (token_type, text, previous_token_type, previous_text, - line_break, unary_context, start) = context - if (_is_binary_operator(token_type, text) and line_break and - not unary_context and - not _is_binary_operator(previous_token_type, - previous_text)): - yield start, "W503 line break before binary operator" - - -@register_check -def break_after_binary_operator(logical_line, tokens): - r""" - Avoid breaks after binary operators. - - The preferred place to break around a binary operator is before the - operator, not after it. - - W504: (width == 0 +\n height == 0) - W504: (width == 0 and\n height == 0) - W504: var = (1 &\n ~2) - - Okay: foo(\n -x) - Okay: foo(x\n []) - Okay: x = '''\n''' + '' - Okay: x = '' + '''\n''' - Okay: foo(x,\n -y) - Okay: foo(x, # comment\n -y) - - The following should be W504 but unary_context is tricky with these - Okay: var = (1 /\n -2) - Okay: var = (1 +\n -1 +\n -2) - """ - prev_start = None - for context in _break_around_binary_operators(tokens): - (token_type, text, previous_token_type, previous_text, - line_break, unary_context, start) = context - if (_is_binary_operator(previous_token_type, previous_text) and - line_break and - not unary_context and - not _is_binary_operator(token_type, text)): - yield prev_start, "W504 line break after binary operator" - prev_start = start - - -@register_check -def comparison_to_singleton(logical_line, noqa): - r"""Comparison to singletons should use "is" or "is not". - - Comparisons to singletons like None should always be done - with "is" or "is not", never the equality operators. - - Okay: if arg is not None: - E711: if arg != None: - E711: if None == arg: - E712: if arg == True: - E712: if False == arg: - - Also, beware of writing if x when you really mean if x is not None - -- e.g. when testing whether a variable or argument that defaults to - None was set to some other value. The other value might have a type - (such as a container) that could be false in a boolean context! - """ - match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line) - if match: - singleton = match.group(1) or match.group(3) - same = (match.group(2) == '==') - - msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) - if singleton in ('None',): - code = 'E711' - else: - code = 'E712' - nonzero = ((singleton == 'True' and same) or - (singleton == 'False' and not same)) - msg += " or 'if %scond:'" % ('' if nonzero else 'not ') - yield match.start(2), ("%s comparison to %s should be %s" % - (code, singleton, msg)) - - -@register_check -def comparison_negative(logical_line): - r"""Negative comparison should be done using "not in" and "is not". - - Okay: if x not in y:\n pass - Okay: assert (X in Y or X is Z) - Okay: if not (X in Y):\n pass - Okay: zz = x is not y - E713: Z = not X in Y - E713: if not X.B in Y:\n pass - E714: if not X is Y:\n pass - E714: Z = not X.B is Y - """ - match = COMPARE_NEGATIVE_REGEX.search(logical_line) - if match: - pos = match.start(1) - if match.group(2) == 'in': - yield pos, "E713 test for membership should be 'not in'" - else: - yield pos, "E714 test for object identity should be 'is not'" - - -@register_check -def comparison_type(logical_line, noqa): - r"""Object type comparisons should always use isinstance(). - - Do not compare types directly. - - Okay: if isinstance(obj, int): - E721: if type(obj) is type(1): - - When checking if an object is a string, keep in mind that it might - be a unicode string too! In Python 2.3, str and unicode have a - common base class, basestring, so you can do: - - Okay: if isinstance(obj, basestring): - Okay: if type(a1) is type(b1): - """ - match = COMPARE_TYPE_REGEX.search(logical_line) - if match and not noqa: - inst = match.group(1) - if inst and isidentifier(inst) and inst not in SINGLETONS: - return # Allow comparison for types which are not obvious - yield match.start(), "E721 do not compare types, use 'isinstance()'" - - -@register_check -def bare_except(logical_line, noqa): - r"""When catching exceptions, mention specific exceptions when - possible. - - Okay: except Exception: - Okay: except BaseException: - E722: except: - """ - if noqa: - return - - regex = re.compile(r"except\s*:") - match = regex.match(logical_line) - if match: - yield match.start(), "E722 do not use bare 'except'" - - -@register_check -def ambiguous_identifier(logical_line, tokens): - r"""Never use the characters 'l', 'O', or 'I' as variable names. - - In some fonts, these characters are indistinguishable from the - numerals one and zero. When tempted to use 'l', use 'L' instead. - - Okay: L = 0 - Okay: o = 123 - Okay: i = 42 - E741: l = 0 - E741: O = 123 - E741: I = 42 - - Variables can be bound in several other contexts, including class - and function definitions, 'global' and 'nonlocal' statements, - exception handlers, and 'with' and 'for' statements. - In addition, we have a special handling for function parameters. - - Okay: except AttributeError as o: - Okay: with lock as L: - Okay: foo(l=12) - Okay: for a in foo(l=12): - E741: except AttributeError as O: - E741: with lock as l: - E741: global I - E741: nonlocal l - E741: def foo(l): - E741: def foo(l=12): - E741: l = foo(l=12) - E741: for l in range(10): - E742: class I(object): - E743: def l(x): - """ - is_func_def = False # Set to true if 'def' is found - parameter_parentheses_level = 0 - idents_to_avoid = ('l', 'O', 'I') - prev_type, prev_text, prev_start, prev_end, __ = tokens[0] - for token_type, text, start, end, line in tokens[1:]: - ident = pos = None - # find function definitions - if prev_text == 'def': - is_func_def = True - # update parameter parentheses level - if parameter_parentheses_level == 0 and \ - prev_type == tokenize.NAME and \ - token_type == tokenize.OP and text == '(': - parameter_parentheses_level = 1 - elif parameter_parentheses_level > 0 and \ - token_type == tokenize.OP: - if text == '(': - parameter_parentheses_level += 1 - elif text == ')': - parameter_parentheses_level -= 1 - # identifiers on the lhs of an assignment operator - if token_type == tokenize.OP and '=' in text and \ - parameter_parentheses_level == 0: - if prev_text in idents_to_avoid: - ident = prev_text - pos = prev_start - # identifiers bound to values with 'as', 'for', - # 'global', or 'nonlocal' - if prev_text in ('as', 'for', 'global', 'nonlocal'): - if text in idents_to_avoid: - ident = text - pos = start - # function parameter definitions - if is_func_def: - if text in idents_to_avoid: - ident = text - pos = start - if prev_text == 'class': - if text in idents_to_avoid: - yield start, "E742 ambiguous class definition '%s'" % text - if prev_text == 'def': - if text in idents_to_avoid: - yield start, "E743 ambiguous function definition '%s'" % text - if ident: - yield pos, "E741 ambiguous variable name '%s'" % ident - prev_type = token_type - prev_text = text - prev_start = start - - -@register_check -def python_3000_has_key(logical_line, noqa): - r"""The {}.has_key() method is removed in Python 3: use the 'in' - operator. - - Okay: if "alph" in d:\n print d["alph"] - W601: assert d.has_key('alph') - """ - pos = logical_line.find('.has_key(') - if pos > -1 and not noqa: - yield pos, "W601 .has_key() is deprecated, use 'in'" - - -@register_check -def python_3000_raise_comma(logical_line): - r"""When raising an exception, use "raise ValueError('message')". - - The older form is removed in Python 3. - - Okay: raise DummyError("Message") - W602: raise DummyError, "Message" - """ - match = RAISE_COMMA_REGEX.match(logical_line) - if match and not RERAISE_COMMA_REGEX.match(logical_line): - yield match.end() - 1, "W602 deprecated form of raising exception" - - -@register_check -def python_3000_not_equal(logical_line): - r"""New code should always use != instead of <>. - - The older syntax is removed in Python 3. - - Okay: if a != 'no': - W603: if a <> 'no': - """ - pos = logical_line.find('<>') - if pos > -1: - yield pos, "W603 '<>' is deprecated, use '!='" - - -@register_check -def python_3000_backticks(logical_line): - r"""Use repr() instead of backticks in Python 3. - - Okay: val = repr(1 + 2) - W604: val = `1 + 2` - """ - pos = logical_line.find('`') - if pos > -1: - yield pos, "W604 backticks are deprecated, use 'repr()'" - - -@register_check -def python_3000_invalid_escape_sequence(logical_line, tokens, noqa): - r"""Invalid escape sequences are deprecated in Python 3.6. - - Okay: regex = r'\.png$' - W605: regex = '\.png$' - """ - if noqa: - return - - # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals - valid = [ - '\n', - '\\', - '\'', - '"', - 'a', - 'b', - 'f', - 'n', - 'r', - 't', - 'v', - '0', '1', '2', '3', '4', '5', '6', '7', - 'x', - - # Escape sequences only recognized in string literals - 'N', - 'u', - 'U', - ] - - for token_type, text, start, end, line in tokens: - if token_type == tokenize.STRING: - start_line, start_col = start - quote = text[-3:] if text[-3:] in ('"""', "'''") else text[-1] - # Extract string modifiers (e.g. u or r) - quote_pos = text.index(quote) - prefix = text[:quote_pos].lower() - start = quote_pos + len(quote) - string = text[start:-len(quote)] - - if 'r' not in prefix: - pos = string.find('\\') - while pos >= 0: - pos += 1 - if string[pos] not in valid: - line = start_line + string.count('\n', 0, pos) - if line == start_line: - col = start_col + len(prefix) + len(quote) + pos - else: - col = pos - string.rfind('\n', 0, pos) - 1 - yield ( - (line, col - 1), - "W605 invalid escape sequence '\\%s'" % - string[pos], - ) - pos = string.find('\\', pos + 1) - - -@register_check -def python_3000_async_await_keywords(logical_line, tokens): - """'async' and 'await' are reserved keywords starting at Python 3.7. - - W606: async = 42 - W606: await = 42 - Okay: async def read(db):\n data = await db.fetch('SELECT ...') - """ - # The Python tokenize library before Python 3.5 recognizes - # async/await as a NAME token. Therefore, use a state machine to - # look for the possible async/await constructs as defined by the - # Python grammar: - # https://docs.python.org/3/reference/grammar.html - - state = None - for token_type, text, start, end, line in tokens: - error = False - - if token_type == tokenize.NL: - continue - - if state is None: - if token_type == tokenize.NAME: - if text == 'async': - state = ('async_stmt', start) - elif text == 'await': - state = ('await', start) - elif (token_type == tokenize.NAME and - text in ('def', 'for')): - state = ('define', start) - - elif state[0] == 'async_stmt': - if token_type == tokenize.NAME and text in ('def', 'with', 'for'): - # One of funcdef, with_stmt, or for_stmt. Return to - # looking for async/await names. - state = None - else: - error = True - elif state[0] == 'await': - if token_type == tokenize.NAME: - # An await expression. Return to looking for async/await - # names. - state = None - elif token_type == tokenize.OP and text == '(': - state = None - else: - error = True - elif state[0] == 'define': - if token_type == tokenize.NAME and text in ('async', 'await'): - error = True - else: - state = None - - if error: - yield ( - state[1], - "W606 'async' and 'await' are reserved keywords starting with " - "Python 3.7", - ) - state = None - - # Last token - if state is not None: - yield ( - state[1], - "W606 'async' and 'await' are reserved keywords starting with " - "Python 3.7", - ) - - -######################################################################## -@register_check -def maximum_doc_length(logical_line, max_doc_length, noqa, tokens): - r"""Limit all doc lines to a maximum of 72 characters. - - For flowing long blocks of text (docstrings or comments), limiting - the length to 72 characters is recommended. - - Reports warning W505 - """ - if max_doc_length is None or noqa: - return - - prev_token = None - skip_lines = set() - # Skip lines that - for token_type, text, start, end, line in tokens: - if token_type not in SKIP_COMMENTS.union([tokenize.STRING]): - skip_lines.add(line) - - for token_type, text, start, end, line in tokens: - # Skip lines that aren't pure strings - if token_type == tokenize.STRING and skip_lines: - continue - if token_type in (tokenize.STRING, tokenize.COMMENT): - # Only check comment-only lines - if prev_token is None or prev_token in SKIP_TOKENS: - lines = line.splitlines() - for line_num, physical_line in enumerate(lines): - if hasattr(physical_line, 'decode'): # Python 2 - # The line could contain multi-byte characters - try: - physical_line = physical_line.decode('utf-8') - except UnicodeError: - pass - if start[0] + line_num == 1 and line.startswith('#!'): - return - length = len(physical_line) - chunks = physical_line.split() - if token_type == tokenize.COMMENT: - if (len(chunks) == 2 and - length - len(chunks[-1]) < MAX_DOC_LENGTH): - continue - if len(chunks) == 1 and line_num + 1 < len(lines): - if (len(chunks) == 1 and - length - len(chunks[-1]) < MAX_DOC_LENGTH): - continue - if length > max_doc_length: - doc_error = (start[0] + line_num, max_doc_length) - yield (doc_error, "W505 doc line too long " - "(%d > %d characters)" - % (length, max_doc_length)) - prev_token = token_type - - -######################################################################## -# Helper functions -######################################################################## - - -if sys.version_info < (3,): - # Python 2: implicit encoding. - def readlines(filename): - """Read the source code.""" - with open(filename, 'rU') as f: - return f.readlines() - isidentifier = re.compile(r'[a-zA-Z_]\w*$').match - stdin_get_value = sys.stdin.read -else: - # Python 3 - def readlines(filename): - """Read the source code.""" - try: - with open(filename, 'rb') as f: - (coding, lines) = tokenize.detect_encoding(f.readline) - f = TextIOWrapper(f, coding, line_buffering=True) - return [line.decode(coding) for line in lines] + f.readlines() - except (LookupError, SyntaxError, UnicodeError): - # Fall back if file encoding is improperly declared - with open(filename, encoding='latin-1') as f: - return f.readlines() - isidentifier = str.isidentifier - - def stdin_get_value(): - """Read the value from stdin.""" - return TextIOWrapper(sys.stdin.buffer, errors='ignore').read() - -noqa = lru_cache(512)(re.compile(r'# no(?:qa|pep8)\b', re.I).search) - - -def expand_indent(line): - r"""Return the amount of indentation. - - Tabs are expanded to the next multiple of 8. - - >>> expand_indent(' ') - 4 - >>> expand_indent('\t') - 8 - >>> expand_indent(' \t') - 8 - >>> expand_indent(' \t') - 16 - """ - line = line.rstrip('\n\r') - if '\t' not in line: - return len(line) - len(line.lstrip()) - result = 0 - for char in line: - if char == '\t': - result = result // 8 * 8 + 8 - elif char == ' ': - result += 1 - else: - break - return result - - -def mute_string(text): - """Replace contents with 'xxx' to prevent syntax matching. - - >>> mute_string('"abc"') - '"xxx"' - >>> mute_string("'''abc'''") - "'''xxx'''" - >>> mute_string("r'abc'") - "r'xxx'" - """ - # String modifiers (e.g. u or r) - start = text.index(text[-1]) + 1 - end = len(text) - 1 - # Triple quotes - if text[-3:] in ('"""', "'''"): - start += 2 - end -= 2 - return text[:start] + 'x' * (end - start) + text[end:] - - -def parse_udiff(diff, patterns=None, parent='.'): - """Return a dictionary of matching lines.""" - # For each file of the diff, the entry key is the filename, - # and the value is a set of row numbers to consider. - rv = {} - path = nrows = None - for line in diff.splitlines(): - if nrows: - if line[:1] != '-': - nrows -= 1 - continue - if line[:3] == '@@ ': - hunk_match = HUNK_REGEX.match(line) - (row, nrows) = [int(g or '1') for g in hunk_match.groups()] - rv[path].update(range(row, row + nrows)) - elif line[:3] == '+++': - path = line[4:].split('\t', 1)[0] - # Git diff will use (i)ndex, (w)ork tree, (c)ommit and - # (o)bject instead of a/b/c/d as prefixes for patches - if path[:2] in ('b/', 'w/', 'i/'): - path = path[2:] - rv[path] = set() - return { - os.path.join(parent, filepath): rows - for (filepath, rows) in rv.items() - if rows and filename_match(filepath, patterns) - } - - -def normalize_paths(value, parent=os.curdir): - """Parse a comma-separated list of paths. - - Return a list of absolute paths. - """ - if not value: - return [] - if isinstance(value, list): - return value - paths = [] - for path in value.split(','): - path = path.strip() - if '/' in path: - path = os.path.abspath(os.path.join(parent, path)) - paths.append(path.rstrip('/')) - return paths - - -def filename_match(filename, patterns, default=True): - """Check if patterns contains a pattern that matches filename. - - If patterns is unspecified, this always returns True. - """ - if not patterns: - return default - return any(fnmatch(filename, pattern) for pattern in patterns) - - -def update_counts(s, counts): - r"""Adds one to the counts of each appearance of characters in s, - for characters in counts""" - for char in s: - if char in counts: - counts[char] += 1 - - -def _is_eol_token(token): - return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n' - - -######################################################################## -# Framework to run all checks -######################################################################## - - -class Checker(object): - """Load a Python source file, tokenize it, check coding style.""" - - def __init__(self, filename=None, lines=None, - options=None, report=None, **kwargs): - if options is None: - options = StyleGuide(kwargs).options - else: - assert not kwargs - self._io_error = None - self._physical_checks = options.physical_checks - self._logical_checks = options.logical_checks - self._ast_checks = options.ast_checks - self.max_line_length = options.max_line_length - self.max_doc_length = options.max_doc_length - self.multiline = False # in a multiline string? - self.hang_closing = options.hang_closing - self.verbose = options.verbose - self.filename = filename - # Dictionary where a checker can store its custom state. - self._checker_states = {} - if filename is None: - self.filename = 'stdin' - self.lines = lines or [] - elif filename == '-': - self.filename = 'stdin' - self.lines = stdin_get_value().splitlines(True) - elif lines is None: - try: - self.lines = readlines(filename) - except IOError: - (exc_type, exc) = sys.exc_info()[:2] - self._io_error = '%s: %s' % (exc_type.__name__, exc) - self.lines = [] - else: - self.lines = lines - if self.lines: - ord0 = ord(self.lines[0][0]) - if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM - if ord0 == 0xfeff: - self.lines[0] = self.lines[0][1:] - elif self.lines[0][:3] == '\xef\xbb\xbf': - self.lines[0] = self.lines[0][3:] - self.report = report or options.report - self.report_error = self.report.error - self.noqa = False - - def report_invalid_syntax(self): - """Check if the syntax is valid.""" - (exc_type, exc) = sys.exc_info()[:2] - if len(exc.args) > 1: - offset = exc.args[1] - if len(offset) > 2: - offset = offset[1:3] - else: - offset = (1, 0) - self.report_error(offset[0], offset[1] or 0, - 'E901 %s: %s' % (exc_type.__name__, exc.args[0]), - self.report_invalid_syntax) - - def readline(self): - """Get the next line from the input buffer.""" - if self.line_number >= self.total_lines: - return '' - line = self.lines[self.line_number] - self.line_number += 1 - if self.indent_char is None and line[:1] in WHITESPACE: - self.indent_char = line[0] - return line - - def run_check(self, check, argument_names): - """Run a check plugin.""" - arguments = [] - for name in argument_names: - arguments.append(getattr(self, name)) - return check(*arguments) - - def init_checker_state(self, name, argument_names): - """Prepare custom state for the specific checker plugin.""" - if 'checker_state' in argument_names: - self.checker_state = self._checker_states.setdefault(name, {}) - - def check_physical(self, line): - """Run all physical checks on a raw input line.""" - self.physical_line = line - for name, check, argument_names in self._physical_checks: - self.init_checker_state(name, argument_names) - result = self.run_check(check, argument_names) - if result is not None: - (offset, text) = result - self.report_error(self.line_number, offset, text, check) - if text[:4] == 'E101': - self.indent_char = line[0] - - def build_tokens_line(self): - """Build a logical line from tokens.""" - logical = [] - comments = [] - length = 0 - prev_row = prev_col = mapping = None - for token_type, text, start, end, line in self.tokens: - if token_type in SKIP_TOKENS: - continue - if not mapping: - mapping = [(0, start)] - if token_type == tokenize.COMMENT: - comments.append(text) - continue - if token_type == tokenize.STRING: - text = mute_string(text) - if prev_row: - (start_row, start_col) = start - if prev_row != start_row: # different row - prev_text = self.lines[prev_row - 1][prev_col - 1] - if prev_text == ',' or (prev_text not in '{[(' and - text not in '}])'): - text = ' ' + text - elif prev_col != start_col: # different column - text = line[prev_col:start_col] + text - logical.append(text) - length += len(text) - mapping.append((length, end)) - (prev_row, prev_col) = end - self.logical_line = ''.join(logical) - self.noqa = comments and noqa(''.join(comments)) - return mapping - - def check_logical(self): - """Build a line from tokens and run all logical checks on it.""" - self.report.increment_logical_line() - mapping = self.build_tokens_line() - if not mapping: - return - - mapping_offsets = [offset for offset, _ in mapping] - (start_row, start_col) = mapping[0][1] - start_line = self.lines[start_row - 1] - self.indent_level = expand_indent(start_line[:start_col]) - if self.blank_before < self.blank_lines: - self.blank_before = self.blank_lines - if self.verbose >= 2: - print(self.logical_line[:80].rstrip()) - for name, check, argument_names in self._logical_checks: - if self.verbose >= 4: - print(' ' + name) - self.init_checker_state(name, argument_names) - for offset, text in self.run_check(check, argument_names) or (): - if not isinstance(offset, tuple): - # As mappings are ordered, bisecting is a fast way - # to find a given offset in them. - token_offset, pos = mapping[bisect.bisect_left( - mapping_offsets, offset)] - offset = (pos[0], pos[1] + offset - token_offset) - self.report_error(offset[0], offset[1], text, check) - if self.logical_line: - self.previous_indent_level = self.indent_level - self.previous_logical = self.logical_line - if not self.indent_level: - self.previous_unindented_logical_line = self.logical_line - self.blank_lines = 0 - self.tokens = [] - - def check_ast(self): - """Build the file's AST and run all AST checks.""" - try: - tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) - except (ValueError, SyntaxError, TypeError): - return self.report_invalid_syntax() - for name, cls, __ in self._ast_checks: - checker = cls(tree, self.filename) - for lineno, offset, text, check in checker.run(): - if not self.lines or not noqa(self.lines[lineno - 1]): - self.report_error(lineno, offset, text, check) - - def generate_tokens(self): - """Tokenize file, run physical line checks and yield tokens.""" - if self._io_error: - self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) - tokengen = tokenize.generate_tokens(self.readline) - try: - for token in tokengen: - if token[2][0] > self.total_lines: - return - self.noqa = token[4] and noqa(token[4]) - self.maybe_check_physical(token) - yield token - except (SyntaxError, tokenize.TokenError): - self.report_invalid_syntax() - - def maybe_check_physical(self, token): - """If appropriate for token, check current physical line(s).""" - # Called after every token, but act only on end of line. - if _is_eol_token(token): - # Obviously, a newline token ends a single physical line. - self.check_physical(token[4]) - elif token[0] == tokenize.STRING and '\n' in token[1]: - # Less obviously, a string that contains newlines is a - # multiline string, either triple-quoted or with internal - # newlines backslash-escaped. Check every physical line in - # the string *except* for the last one: its newline is - # outside of the multiline string, so we consider it a - # regular physical line, and will check it like any other - # physical line. - # - # Subtleties: - # - we don't *completely* ignore the last line; if it - # contains the magical "# noqa" comment, we disable all - # physical checks for the entire multiline string - # - have to wind self.line_number back because initially it - # points to the last line of the string, and we want - # check_physical() to give accurate feedback - if noqa(token[4]): - return - self.multiline = True - self.line_number = token[2][0] - _, src, (_, offset), _, _ = token - src = self.lines[self.line_number - 1][:offset] + src - for line in src.split('\n')[:-1]: - self.check_physical(line + '\n') - self.line_number += 1 - self.multiline = False - - def check_all(self, expected=None, line_offset=0): - """Run all checks on the input file.""" - self.report.init_file(self.filename, self.lines, expected, line_offset) - self.total_lines = len(self.lines) - if self._ast_checks: - self.check_ast() - self.line_number = 0 - self.indent_char = None - self.indent_level = self.previous_indent_level = 0 - self.previous_logical = '' - self.previous_unindented_logical_line = '' - self.tokens = [] - self.blank_lines = self.blank_before = 0 - parens = 0 - for token in self.generate_tokens(): - self.tokens.append(token) - token_type, text = token[0:2] - if self.verbose >= 3: - if token[2][0] == token[3][0]: - pos = '[%s:%s]' % (token[2][1] or '', token[3][1]) - else: - pos = 'l.%s' % token[3][0] - print('l.%s\t%s\t%s\t%r' % - (token[2][0], pos, tokenize.tok_name[token[0]], text)) - if token_type == tokenize.OP: - if text in '([{': - parens += 1 - elif text in '}])': - parens -= 1 - elif not parens: - if token_type in NEWLINE: - if token_type == tokenize.NEWLINE: - self.check_logical() - self.blank_before = 0 - elif len(self.tokens) == 1: - # The physical line contains only this token. - self.blank_lines += 1 - del self.tokens[0] - else: - self.check_logical() - if self.tokens: - self.check_physical(self.lines[-1]) - self.check_logical() - return self.report.get_file_results() - - -class BaseReport(object): - """Collect the results of the checks.""" - - print_filename = False - - def __init__(self, options): - self._benchmark_keys = options.benchmark_keys - self._ignore_code = options.ignore_code - # Results - self.elapsed = 0 - self.total_errors = 0 - self.counters = dict.fromkeys(self._benchmark_keys, 0) - self.messages = {} - - def start(self): - """Start the timer.""" - self._start_time = time.time() - - def stop(self): - """Stop the timer.""" - self.elapsed = time.time() - self._start_time - - def init_file(self, filename, lines, expected, line_offset): - """Signal a new file.""" - self.filename = filename - self.lines = lines - self.expected = expected or () - self.line_offset = line_offset - self.file_errors = 0 - self.counters['files'] += 1 - self.counters['physical lines'] += len(lines) - - def increment_logical_line(self): - """Signal a new logical line.""" - self.counters['logical lines'] += 1 - - def error(self, line_number, offset, text, check): - """Report an error, according to options.""" - code = text[:4] - if self._ignore_code(code): - return - if code in self.counters: - self.counters[code] += 1 - else: - self.counters[code] = 1 - self.messages[code] = text[5:] - # Don't care about expected errors or warnings - if code in self.expected: - return - if self.print_filename and not self.file_errors: - print(self.filename) - self.file_errors += 1 - self.total_errors += 1 - return code - - def get_file_results(self): - """Return the count of errors and warnings for this file.""" - return self.file_errors - - def get_count(self, prefix=''): - """Return the total count of errors and warnings.""" - return sum(self.counters[key] - for key in self.messages if key.startswith(prefix)) - - def get_statistics(self, prefix=''): - """Get statistics for message codes that start with the prefix. - - prefix='' matches all errors and warnings - prefix='E' matches all errors - prefix='W' matches all warnings - prefix='E4' matches all errors that have to do with imports - """ - return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) - for key in sorted(self.messages) if key.startswith(prefix)] - - def print_statistics(self, prefix=''): - """Print overall statistics (number of errors and warnings).""" - for line in self.get_statistics(prefix): - print(line) - - def print_benchmark(self): - """Print benchmark numbers.""" - print('%-7.2f %s' % (self.elapsed, 'seconds elapsed')) - if self.elapsed: - for key in self._benchmark_keys: - print('%-7d %s per second (%d total)' % - (self.counters[key] / self.elapsed, key, - self.counters[key])) - - -class FileReport(BaseReport): - """Collect the results of the checks and print the filenames.""" - - print_filename = True - - -class StandardReport(BaseReport): - """Collect and print the results of the checks.""" - - def __init__(self, options): - super(StandardReport, self).__init__(options) - self._fmt = REPORT_FORMAT.get(options.format.lower(), - options.format) - self._repeat = options.repeat - self._show_source = options.show_source - self._show_pep8 = options.show_pep8 - - def init_file(self, filename, lines, expected, line_offset): - """Signal a new file.""" - self._deferred_print = [] - return super(StandardReport, self).init_file( - filename, lines, expected, line_offset) - - def error(self, line_number, offset, text, check): - """Report an error, according to options.""" - code = super(StandardReport, self).error(line_number, offset, - text, check) - if code and (self.counters[code] == 1 or self._repeat): - self._deferred_print.append( - (line_number, offset, code, text[5:], check.__doc__)) - return code - - def get_file_results(self): - """Print results and return the overall count for this file.""" - self._deferred_print.sort() - for line_number, offset, code, text, doc in self._deferred_print: - print(self._fmt % { - 'path': self.filename, - 'row': self.line_offset + line_number, 'col': offset + 1, - 'code': code, 'text': text, - }) - if self._show_source: - if line_number > len(self.lines): - line = '' - else: - line = self.lines[line_number - 1] - print(line.rstrip()) - print(re.sub(r'\S', ' ', line[:offset]) + '^') - if self._show_pep8 and doc: - print(' ' + doc.strip()) - - # stdout is block buffered when not stdout.isatty(). - # line can be broken where buffer boundary since other - # processes write to same file. - # flush() after print() to avoid buffer boundary. - # Typical buffer size is 8192. line written safely when - # len(line) < 8192. - sys.stdout.flush() - return self.file_errors - - -class DiffReport(StandardReport): - """Collect and print the results for the changed lines only.""" - - def __init__(self, options): - super(DiffReport, self).__init__(options) - self._selected = options.selected_lines - - def error(self, line_number, offset, text, check): - if line_number not in self._selected[self.filename]: - return - return super(DiffReport, self).error(line_number, offset, text, check) - - -class StyleGuide(object): - """Initialize a PEP-8 instance with few options.""" - - def __init__(self, *args, **kwargs): - # build options from the command line - self.checker_class = kwargs.pop('checker_class', Checker) - parse_argv = kwargs.pop('parse_argv', False) - config_file = kwargs.pop('config_file', False) - parser = kwargs.pop('parser', None) - # build options from dict - options_dict = dict(*args, **kwargs) - arglist = None if parse_argv else options_dict.get('paths', None) - verbose = options_dict.get('verbose', None) - options, self.paths = process_options( - arglist, parse_argv, config_file, parser, verbose) - if options_dict: - options.__dict__.update(options_dict) - if 'paths' in options_dict: - self.paths = options_dict['paths'] - - self.runner = self.input_file - self.options = options - - if not options.reporter: - options.reporter = BaseReport if options.quiet else StandardReport - - options.select = tuple(options.select or ()) - if not (options.select or options.ignore or - options.testsuite or options.doctest) and DEFAULT_IGNORE: - # The default choice: ignore controversial checks - options.ignore = tuple(DEFAULT_IGNORE.split(',')) - else: - # Ignore all checks which are not explicitly selected - options.ignore = ('',) if options.select else tuple(options.ignore) - options.benchmark_keys = BENCHMARK_KEYS[:] - options.ignore_code = self.ignore_code - options.physical_checks = self.get_checks('physical_line') - options.logical_checks = self.get_checks('logical_line') - options.ast_checks = self.get_checks('tree') - self.init_report() - - def init_report(self, reporter=None): - """Initialize the report instance.""" - self.options.report = (reporter or self.options.reporter)(self.options) - return self.options.report - - def check_files(self, paths=None): - """Run all checks on the paths.""" - if paths is None: - paths = self.paths - report = self.options.report - runner = self.runner - report.start() - try: - for path in paths: - if os.path.isdir(path): - self.input_dir(path) - elif not self.excluded(path): - runner(path) - except KeyboardInterrupt: - print('... stopped') - report.stop() - return report - - def input_file(self, filename, lines=None, expected=None, line_offset=0): - """Run all checks on a Python source file.""" - if self.options.verbose: - print('checking %s' % filename) - fchecker = self.checker_class( - filename, lines=lines, options=self.options) - return fchecker.check_all(expected=expected, line_offset=line_offset) - - def input_dir(self, dirname): - """Check all files in this directory and all subdirectories.""" - dirname = dirname.rstrip('/') - if self.excluded(dirname): - return 0 - counters = self.options.report.counters - verbose = self.options.verbose - filepatterns = self.options.filename - runner = self.runner - for root, dirs, files in os.walk(dirname): - if verbose: - print('directory ' + root) - counters['directories'] += 1 - for subdir in sorted(dirs): - if self.excluded(subdir, root): - dirs.remove(subdir) - for filename in sorted(files): - # contain a pattern that matches? - if ((filename_match(filename, filepatterns) and - not self.excluded(filename, root))): - runner(os.path.join(root, filename)) - - def excluded(self, filename, parent=None): - """Check if the file should be excluded. - - Check if 'options.exclude' contains a pattern matching filename. - """ - if not self.options.exclude: - return False - basename = os.path.basename(filename) - if filename_match(basename, self.options.exclude): - return True - if parent: - filename = os.path.join(parent, filename) - filename = os.path.abspath(filename) - return filename_match(filename, self.options.exclude) - - def ignore_code(self, code): - """Check if the error code should be ignored. - - If 'options.select' contains a prefix of the error code, - return False. Else, if 'options.ignore' contains a prefix of - the error code, return True. - """ - if len(code) < 4 and any(s.startswith(code) - for s in self.options.select): - return False - return (code.startswith(self.options.ignore) and - not code.startswith(self.options.select)) - - def get_checks(self, argument_name): - """Get all the checks for this category. - - Find all globally visible functions where the first argument - name starts with argument_name and which contain selected tests. - """ - checks = [] - for check, attrs in _checks[argument_name].items(): - (codes, args) = attrs - if any(not (code and self.ignore_code(code)) for code in codes): - checks.append((check.__name__, check, args)) - return sorted(checks) - - -def get_parser(prog='pycodestyle', version=__version__): - """Create the parser for the program.""" - parser = OptionParser(prog=prog, version=version, - usage="%prog [options] input ...") - parser.config_options = [ - 'exclude', 'filename', 'select', 'ignore', 'max-line-length', - 'max-doc-length', 'hang-closing', 'count', 'format', 'quiet', - 'show-pep8', 'show-source', 'statistics', 'verbose'] - parser.add_option('-v', '--verbose', default=0, action='count', - help="print status messages, or debug with -vv") - parser.add_option('-q', '--quiet', default=0, action='count', - help="report only file names, or nothing with -qq") - parser.add_option('-r', '--repeat', default=True, action='store_true', - help="(obsolete) show all occurrences of the same error") - parser.add_option('--first', action='store_false', dest='repeat', - help="show first occurrence of each error") - parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, - help="exclude files or directories which match these " - "comma separated patterns (default: %default)") - parser.add_option('--filename', metavar='patterns', default='*.py', - help="when parsing directories, only check filenames " - "matching these comma separated patterns " - "(default: %default)") - parser.add_option('--select', metavar='errors', default='', - help="select errors and warnings (e.g. E,W6)") - parser.add_option('--ignore', metavar='errors', default='', - help="skip errors and warnings (e.g. E4,W) " - "(default: %s)" % DEFAULT_IGNORE) - parser.add_option('--show-source', action='store_true', - help="show source code for each error") - parser.add_option('--show-pep8', action='store_true', - help="show text of PEP 8 for each error " - "(implies --first)") - parser.add_option('--statistics', action='store_true', - help="count errors and warnings") - parser.add_option('--count', action='store_true', - help="print total number of errors and warnings " - "to standard error and set exit code to 1 if " - "total is not null") - parser.add_option('--max-line-length', type='int', metavar='n', - default=MAX_LINE_LENGTH, - help="set maximum allowed line length " - "(default: %default)") - parser.add_option('--max-doc-length', type='int', metavar='n', - default=None, - help="set maximum allowed doc line length and perform " - "these checks (unchecked if not set)") - parser.add_option('--hang-closing', action='store_true', - help="hang closing bracket instead of matching " - "indentation of opening bracket's line") - parser.add_option('--format', metavar='format', default='default', - help="set the error format [default|pylint|]") - parser.add_option('--diff', action='store_true', - help="report changes only within line number ranges in " - "the unified diff received on STDIN") - group = parser.add_option_group("Testing Options") - if os.path.exists(TESTSUITE_PATH): - group.add_option('--testsuite', metavar='dir', - help="run regression tests from dir") - group.add_option('--doctest', action='store_true', - help="run doctest on myself") - group.add_option('--benchmark', action='store_true', - help="measure processing speed") - return parser - - -def read_config(options, args, arglist, parser): - """Read and parse configurations. - - If a config file is specified on the command line with the - "--config" option, then only it is used for configuration. - - Otherwise, the user configuration (~/.config/pycodestyle) and any - local configurations in the current directory or above will be - merged together (in that order) using the read method of - ConfigParser. - """ - config = RawConfigParser() - - cli_conf = options.config - - local_dir = os.curdir - - if USER_CONFIG and os.path.isfile(USER_CONFIG): - if options.verbose: - print('user configuration: %s' % USER_CONFIG) - config.read(USER_CONFIG) - - parent = tail = args and os.path.abspath(os.path.commonprefix(args)) - while tail: - if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): - local_dir = parent - if options.verbose: - print('local configuration: in %s' % parent) - break - (parent, tail) = os.path.split(parent) - - if cli_conf and os.path.isfile(cli_conf): - if options.verbose: - print('cli configuration: %s' % cli_conf) - config.read(cli_conf) - - pycodestyle_section = None - if config.has_section(parser.prog): - pycodestyle_section = parser.prog - elif config.has_section('pep8'): - pycodestyle_section = 'pep8' # Deprecated - warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') - - if pycodestyle_section: - option_list = {o.dest: o.type or o.action for o in parser.option_list} - - # First, read the default values - (new_options, __) = parser.parse_args([]) - - # Second, parse the configuration - for opt in config.options(pycodestyle_section): - if opt.replace('_', '-') not in parser.config_options: - print(" unknown option '%s' ignored" % opt) - continue - if options.verbose > 1: - print(" %s = %s" % (opt, - config.get(pycodestyle_section, opt))) - normalized_opt = opt.replace('-', '_') - opt_type = option_list[normalized_opt] - if opt_type in ('int', 'count'): - value = config.getint(pycodestyle_section, opt) - elif opt_type in ('store_true', 'store_false'): - value = config.getboolean(pycodestyle_section, opt) - else: - value = config.get(pycodestyle_section, opt) - if normalized_opt == 'exclude': - value = normalize_paths(value, local_dir) - setattr(new_options, normalized_opt, value) - - # Third, overwrite with the command-line options - (options, __) = parser.parse_args(arglist, values=new_options) - options.doctest = options.testsuite = False - return options - - -def process_options(arglist=None, parse_argv=False, config_file=None, - parser=None, verbose=None): - """Process options passed either via arglist or command line args. - - Passing in the ``config_file`` parameter allows other tools, such as - flake8 to specify their own options to be processed in pycodestyle. - """ - if not parser: - parser = get_parser() - if not parser.has_option('--config'): - group = parser.add_option_group("Configuration", description=( - "The project options are read from the [%s] section of the " - "tox.ini file or the setup.cfg file located in any parent folder " - "of the path(s) being processed. Allowed options are: %s." % - (parser.prog, ', '.join(parser.config_options)))) - group.add_option('--config', metavar='path', default=config_file, - help="user config file location") - # Don't read the command line if the module is used as a library. - if not arglist and not parse_argv: - arglist = [] - # If parse_argv is True and arglist is None, arguments are - # parsed from the command line (sys.argv) - (options, args) = parser.parse_args(arglist) - options.reporter = None - - # If explicitly specified verbosity, override any `-v` CLI flag - if verbose is not None: - options.verbose = verbose - - if options.ensure_value('testsuite', False): - args.append(options.testsuite) - elif not options.ensure_value('doctest', False): - if parse_argv and not args: - if options.diff or any(os.path.exists(name) - for name in PROJECT_CONFIG): - args = ['.'] - else: - parser.error('input not specified') - options = read_config(options, args, arglist, parser) - options.reporter = parse_argv and options.quiet == 1 and FileReport - - options.filename = _parse_multi_options(options.filename) - options.exclude = normalize_paths(options.exclude) - options.select = _parse_multi_options(options.select) - options.ignore = _parse_multi_options(options.ignore) - - if options.diff: - options.reporter = DiffReport - stdin = stdin_get_value() - options.selected_lines = parse_udiff(stdin, options.filename, args[0]) - args = sorted(options.selected_lines) - - return options, args - - -def _parse_multi_options(options, split_token=','): - r"""Split and strip and discard empties. - - Turns the following: - - A, - B, - - into ["A", "B"] - """ - if options: - return [o.strip() for o in options.split(split_token) if o.strip()] - else: - return options - - -def _main(): - """Parse options and run checks on Python source.""" - import signal - - # Handle "Broken pipe" gracefully - try: - signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) - except AttributeError: - pass # not supported on Windows - - style_guide = StyleGuide(parse_argv=True) - options = style_guide.options - - if options.doctest or options.testsuite: - from testsuite.support import run_tests - report = run_tests(style_guide) - else: - report = style_guide.check_files() - - if options.statistics: - report.print_statistics() - - if options.benchmark: - report.print_benchmark() - - if options.testsuite and not options.quiet: - report.print_results() - - if report.total_errors: - if options.count: - sys.stderr.write(str(report.total_errors) + '\n') - sys.exit(1) - - -if __name__ == '__main__': - _main() diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/INSTALLER b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/LICENSE b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/LICENSE deleted file mode 100644 index ac69ec13..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017, 2018, 2019 Samuel Colvin and other contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/METADATA b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/METADATA deleted file mode 100644 index 81ead04a..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/METADATA +++ /dev/null @@ -1,814 +0,0 @@ -Metadata-Version: 2.1 -Name: pydantic -Version: 1.7.2 -Summary: Data validation and settings management using python 3.6 type hinting -Home-page: https://github.com/samuelcolvin/pydantic -Author: Samuel Colvin -Author-email: s@muelcolvin.com -License: MIT -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Information Technology -Classifier: Intended Audience :: System Administrators -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: Unix -Classifier: Operating System :: POSIX :: Linux -Classifier: Environment :: Console -Classifier: Environment :: MacOS X -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Internet -Requires-Python: >=3.6 -Description-Content-Type: text/markdown -Requires-Dist: dataclasses (>=0.6) ; python_version < "3.7" -Provides-Extra: dotenv -Requires-Dist: python-dotenv (>=0.10.4) ; extra == 'dotenv' -Provides-Extra: email -Requires-Dist: email-validator (>=1.0.3) ; extra == 'email' -Provides-Extra: typing_extensions -Requires-Dist: typing-extensions (>=3.7.2) ; extra == 'typing_extensions' - -# pydantic - -[![CI](https://github.com/samuelcolvin/pydantic/workflows/CI/badge.svg?event=push)](https://github.com/samuelcolvin/pydantic/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI) -[![Coverage](https://codecov.io/gh/samuelcolvin/pydantic/branch/master/graph/badge.svg)](https://codecov.io/gh/samuelcolvin/pydantic) -[![pypi](https://img.shields.io/pypi/v/pydantic.svg)](https://pypi.python.org/pypi/pydantic) -[![CondaForge](https://img.shields.io/conda/v/conda-forge/pydantic.svg)](https://anaconda.org/conda-forge/pydantic) -[![downloads](https://img.shields.io/pypi/dm/pydantic.svg)](https://pypistats.org/packages/pydantic) -[![versions](https://img.shields.io/pypi/pyversions/pydantic.svg)](https://github.com/samuelcolvin/pydantic) -[![license](https://img.shields.io/github/license/samuelcolvin/pydantic.svg)](https://github.com/samuelcolvin/pydantic/blob/master/LICENSE) - -Data validation and settings management using Python type hinting. - -Fast and extensible, *pydantic* plays nicely with your linters/IDE/brain. -Define how data should be in pure, canonical Python 3.6+; validate it with *pydantic*. - -## Help - -See [documentation](https://pydantic-docs.helpmanual.io/) for more details. - -## Installation - -Install using `pip install -U pydantic` or `conda install pydantic -c conda-forge`. -For more installation options to make *pydantic* even faster, -see the [Install](https://pydantic-docs.helpmanual.io/install/) section in the documentation. - -## A Simple Example - -```py -from datetime import datetime -from typing import List, Optional -from pydantic import BaseModel - -class User(BaseModel): - id: int - name = 'John Doe' - signup_ts: Optional[datetime] = None - friends: List[int] = [] - -external_data = {'id': '123', 'signup_ts': '2017-06-01 12:22', 'friends': [1, '2', b'3']} -user = User(**external_data) -print(user) -#> User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] -print(user.id) -#> 123 -``` - -## Contributing - -For guidance on setting up a development environment and how to make a -contribution to *pydantic*, see -[Contributing to Pydantic](https://pydantic-docs.helpmanual.io/contributing/). - -## Reporting a Security Vulnerability - -See our [security policy](https://github.com/samuelcolvin/pydantic/security/policy). - - -## v1.7.2 (2020-11-01) - -* fix slow `GenericModel` concrete model creation, allow `GenericModel` concrete name reusing in module, [#2078](https://github.com/samuelcolvin/pydantic/issues/2078) by [@MrMrRobat](https://github.com/MrMrRobat) -* keep the order of the fields when `validate_assignment` is set, [#2073](https://github.com/samuelcolvin/pydantic/issues/2073) by [@PrettyWood](https://github.com/PrettyWood) -* forward all the params of the stdlib `dataclass` when converted into _pydantic_ `dataclass`, [#2065](https://github.com/samuelcolvin/pydantic/issues/2065) by [@PrettyWood](https://github.com/PrettyWood) - -## v1.7.1 (2020-10-28) - -Thank you to pydantic's sponsors: -@timdrijvers, [@BCarley](https://github.com/BCarley), [@chdsbd](https://github.com/chdsbd), [@tiangolo](https://github.com/tiangolo), [@matin](https://github.com/matin), [@linusg](https://github.com/linusg), [@kevinalh](https://github.com/kevinalh), [@jorgecarleitao](https://github.com/jorgecarleitao), [@koxudaxi](https://github.com/koxudaxi), [@primer-api](https://github.com/primer-api), [@mkeen](https://github.com/mkeen) -for their kind support. - -* fix annotation of `validate_arguments` when passing configuration as argument, [#2055](https://github.com/samuelcolvin/pydantic/issues/2055) by [@layday](https://github.com/layday) -* Fix mypy assignment error when using `PrivateAttr`, [#2048](https://github.com/samuelcolvin/pydantic/issues/2048) by [@aphedges](https://github.com/aphedges) -* fix `underscore_attrs_are_private` causing `TypeError` when overriding `__init__`, [#2047](https://github.com/samuelcolvin/pydantic/issues/2047) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fixed regression introduced in v1.7 involving exception handling in field validators when `validate_assignment=True`, [#2044](https://github.com/samuelcolvin/pydantic/issues/2044) by [@johnsabath](https://github.com/johnsabath) -* fix: _pydantic_ `dataclass` can inherit from stdlib `dataclass` - and `Config.arbitrary_types_allowed` is supported, [#2042](https://github.com/samuelcolvin/pydantic/issues/2042) by [@PrettyWood](https://github.com/PrettyWood) - -## v1.7 (2020-10-26) - -Thank you to pydantic's sponsors: -@timdrijvers, [@BCarley](https://github.com/BCarley), [@chdsbd](https://github.com/chdsbd), [@tiangolo](https://github.com/tiangolo), [@matin](https://github.com/matin), [@linusg](https://github.com/linusg), [@kevinalh](https://github.com/kevinalh), [@jorgecarleitao](https://github.com/jorgecarleitao), [@koxudaxi](https://github.com/koxudaxi), [@primer-api](https://github.com/primer-api) -for their kind support. - -### Highlights - -* python 3.9 support, thanks [@PrettyWood](https://github.com/PrettyWood) -* [Private model attributes](https://pydantic-docs.helpmanual.io/usage/models/#private-model-attributes), thanks [@MrMrRobat](https://github.com/MrMrRobat) -* ["secrets files" support in `BaseSettings`](https://pydantic-docs.helpmanual.io/usage/settings/#secret-support), thanks [@mdgilene](https://github.com/mdgilene) -* [convert stdlib dataclasses to pydantic dataclasses and use stdlib dataclasses in models](https://pydantic-docs.helpmanual.io/usage/dataclasses/#stdlib-dataclasses-and-pydantic-dataclasses), thanks [@PrettyWood](https://github.com/PrettyWood) - -### Changes - -* **Breaking Change:** remove `__field_defaults__`, add `default_factory` support with `BaseModel.construct`. - Use `.get_default()` method on fields in `__fields__` attribute instead, [#1732](https://github.com/samuelcolvin/pydantic/issues/1732) by [@PrettyWood](https://github.com/PrettyWood) -* Rearrange CI to run linting as a separate job, split install recipes for different tasks, [#2020](https://github.com/samuelcolvin/pydantic/issues/2020) by [@samuelcolvin](https://github.com/samuelcolvin) -* Allows subclasses of generic models to make some, or all, of the superclass's type parameters concrete, while - also defining new type parameters in the subclass, [#2005](https://github.com/samuelcolvin/pydantic/issues/2005) by [@choogeboom](https://github.com/choogeboom) -* Call validator with the correct `values` parameter type in `BaseModel.__setattr__`, - when `validate_assignment = True` in model config, [#1999](https://github.com/samuelcolvin/pydantic/issues/1999) by [@me-ransh](https://github.com/me-ransh) -* Force `fields.Undefined` to be a singleton object, fixing inherited generic model schemas, [#1981](https://github.com/samuelcolvin/pydantic/issues/1981) by [@daviskirk](https://github.com/daviskirk) -* Include tests in source distributions, [#1976](https://github.com/samuelcolvin/pydantic/issues/1976) by [@sbraz](https://github.com/sbraz) -* Add ability to use `min_length/max_length` constraints with secret types, [#1974](https://github.com/samuelcolvin/pydantic/issues/1974) by [@uriyyo](https://github.com/uriyyo) -* Also check `root_validators` when `validate_assignment` is on, [#1971](https://github.com/samuelcolvin/pydantic/issues/1971) by [@PrettyWood](https://github.com/PrettyWood) -* Fix const validators not running when custom validators are present, [#1957](https://github.com/samuelcolvin/pydantic/issues/1957) by [@hmvp](https://github.com/hmvp) -* add `deque` to field types, [#1935](https://github.com/samuelcolvin/pydantic/issues/1935) by [@wozniakty](https://github.com/wozniakty) -* add basic support for python 3.9, [#1832](https://github.com/samuelcolvin/pydantic/issues/1832) by [@PrettyWood](https://github.com/PrettyWood) -* Fix typo in the anchor of exporting_models.md#modelcopy and incorrect description, [#1821](https://github.com/samuelcolvin/pydantic/issues/1821) by [@KimMachineGun](https://github.com/KimMachineGun) -* Added ability for `BaseSettings` to read "secret files", [#1820](https://github.com/samuelcolvin/pydantic/issues/1820) by [@mdgilene](https://github.com/mdgilene) -* add `parse_raw_as` utility function, [#1812](https://github.com/samuelcolvin/pydantic/issues/1812) by [@PrettyWood](https://github.com/PrettyWood) -* Support home directory relative paths for `dotenv` files (e.g. `~/.env`), [#1803](https://github.com/samuelcolvin/pydantic/issues/1803) by [@PrettyWood](https://github.com/PrettyWood) -* Clarify documentation for `parse_file` to show that the argument - should be a file *path* not a file-like object, [#1794](https://github.com/samuelcolvin/pydantic/issues/1794) by [@mdavis-xyz](https://github.com/mdavis-xyz) -* Fix false positive from mypy plugin when a class nested within a `BaseModel` is named `Model`, [#1770](https://github.com/samuelcolvin/pydantic/issues/1770) by [@selimb](https://github.com/selimb) -* add basic support of Pattern type in schema generation, [#1767](https://github.com/samuelcolvin/pydantic/issues/1767) by [@PrettyWood](https://github.com/PrettyWood) -* Support custom title, description and default in schema of enums, [#1748](https://github.com/samuelcolvin/pydantic/issues/1748) by [@PrettyWood](https://github.com/PrettyWood) -* Properly represent `Literal` Enums when `use_enum_values` is True, [#1747](https://github.com/samuelcolvin/pydantic/issues/1747) by [@noelevans](https://github.com/noelevans) -* Allows timezone information to be added to strings to be formatted as time objects. Permitted formats are `Z` for UTC - or an offset for absolute positive or negative time shifts. Or the timezone data can be omitted, [#1744](https://github.com/samuelcolvin/pydantic/issues/1744) by [@noelevans](https://github.com/noelevans) -* Add stub `__init__` with python 3.6 signature for `ForwardRef`, [#1738](https://github.com/samuelcolvin/pydantic/issues/1738) by [@sirtelemak](https://github.com/sirtelemak) -* Fix behaviour with forward refs and optional fields in nested models, [#1736](https://github.com/samuelcolvin/pydantic/issues/1736) by [@PrettyWood](https://github.com/PrettyWood) -* add `Enum` and `IntEnum` as valid types for fields, [#1735](https://github.com/samuelcolvin/pydantic/issues/1735) by [@PrettyWood](https://github.com/PrettyWood) -* Change default value of `__module__` argument of `create_model` from `None` to `'pydantic.main'`. - Set reference of created concrete model to it's module to allow pickling (not applied to models created in - functions), [#1686](https://github.com/samuelcolvin/pydantic/issues/1686) by [@MrMrRobat](https://github.com/MrMrRobat) -* Add private attributes support, [#1679](https://github.com/samuelcolvin/pydantic/issues/1679) by [@MrMrRobat](https://github.com/MrMrRobat) -* add `config` to `@validate_arguments`, [#1663](https://github.com/samuelcolvin/pydantic/issues/1663) by [@samuelcolvin](https://github.com/samuelcolvin) -* Allow descendant Settings models to override env variable names for the fields defined in parent Settings models with - `env` in their `Config`. Previously only `env_prefix` configuration option was applicable, [#1561](https://github.com/samuelcolvin/pydantic/issues/1561) by [@ojomio](https://github.com/ojomio) -* Support `ref_template` when creating schema `$ref`s, [#1479](https://github.com/samuelcolvin/pydantic/issues/1479) by [@kilo59](https://github.com/kilo59) -* Add a `__call__` stub to `PyObject` so that mypy will know that it is callable, [#1352](https://github.com/samuelcolvin/pydantic/issues/1352) by [@brianmaissy](https://github.com/brianmaissy) -* `pydantic.dataclasses.dataclass` decorator now supports built-in `dataclasses.dataclass`. - It is hence possible to convert an existing `dataclass` easily to add *pydantic* validation. - Moreover nested dataclasses are also supported, [#744](https://github.com/samuelcolvin/pydantic/issues/744) by [@PrettyWood](https://github.com/PrettyWood) - -## v1.6.1 (2020-07-15) - -* fix validation and parsing of nested models with `default_factory`, [#1710](https://github.com/samuelcolvin/pydantic/issues/1710) by [@PrettyWood](https://github.com/PrettyWood) - -## v1.6 (2020-07-11) - -Thank you to pydantic's sponsors: [@matin](https://github.com/matin), [@tiangolo](https://github.com/tiangolo), [@chdsbd](https://github.com/chdsbd), [@jorgecarleitao](https://github.com/jorgecarleitao), and 1 anonymous sponsor for their kind support. - -* Modify validators for `conlist` and `conset` to not have `always=True`, [#1682](https://github.com/samuelcolvin/pydantic/issues/1682) by [@samuelcolvin](https://github.com/samuelcolvin) -* add port check to `AnyUrl` (can't exceed 65536) ports are 16 insigned bits: `0 <= port <= 2**16-1` src: [rfc793 header format](https://tools.ietf.org/html/rfc793#section-3.1), [#1654](https://github.com/samuelcolvin/pydantic/issues/1654) by [@flapili](https://github.com/flapili) -* Document default `regex` anchoring semantics, [#1648](https://github.com/samuelcolvin/pydantic/issues/1648) by [@yurikhan](https://github.com/yurikhan) -* Use `chain.from_iterable` in class_validators.py. This is a faster and more idiomatic way of using `itertools.chain`. - Instead of computing all the items in the iterable and storing them in memory, they are computed one-by-one and never - stored as a huge list. This can save on both runtime and memory space, [#1642](https://github.com/samuelcolvin/pydantic/issues/1642) by [@cool-RR](https://github.com/cool-RR) -* Add `conset()`, analogous to `conlist()`, [#1623](https://github.com/samuelcolvin/pydantic/issues/1623) by [@patrickkwang](https://github.com/patrickkwang) -* make *pydantic* errors (un)pickable, [#1616](https://github.com/samuelcolvin/pydantic/issues/1616) by [@PrettyWood](https://github.com/PrettyWood) -* Allow custom encoding for `dotenv` files, [#1615](https://github.com/samuelcolvin/pydantic/issues/1615) by [@PrettyWood](https://github.com/PrettyWood) -* Ensure `SchemaExtraCallable` is always defined to get type hints on BaseConfig, [#1614](https://github.com/samuelcolvin/pydantic/issues/1614) by [@PrettyWood](https://github.com/PrettyWood) -* Update datetime parser to support negative timestamps, [#1600](https://github.com/samuelcolvin/pydantic/issues/1600) by [@mlbiche](https://github.com/mlbiche) -* Update mypy, remove `AnyType` alias for `Type[Any]`, [#1598](https://github.com/samuelcolvin/pydantic/issues/1598) by [@samuelcolvin](https://github.com/samuelcolvin) -* Adjust handling of root validators so that errors are aggregated from _all_ failing root validators, instead of reporting on only the first root validator to fail, [#1586](https://github.com/samuelcolvin/pydantic/issues/1586) by [@beezee](https://github.com/beezee) -* Make `__modify_schema__` on Enums apply to the enum schema rather than fields that use the enum, [#1581](https://github.com/samuelcolvin/pydantic/issues/1581) by [@therefromhere](https://github.com/therefromhere) -* Fix behavior of `__all__` key when used in conjunction with index keys in advanced include/exclude of fields that are sequences, [#1579](https://github.com/samuelcolvin/pydantic/issues/1579) by [@xspirus](https://github.com/xspirus) -* Subclass validators do not run when referencing a `List` field defined in a parent class when `each_item=True`. Added an example to the docs illustrating this, [#1566](https://github.com/samuelcolvin/pydantic/issues/1566) by [@samueldeklund](https://github.com/samueldeklund) -* change `schema.field_class_to_schema` to support `frozenset` in schema, [#1557](https://github.com/samuelcolvin/pydantic/issues/1557) by [@wangpeibao](https://github.com/wangpeibao) -* Call `__modify_schema__` only for the field schema, [#1552](https://github.com/samuelcolvin/pydantic/issues/1552) by [@PrettyWood](https://github.com/PrettyWood) -* Move the assignment of `field.validate_always` in `fields.py` so the `always` parameter of validators work on inheritance, [#1545](https://github.com/samuelcolvin/pydantic/issues/1545) by [@dcHHH](https://github.com/dcHHH) -* Added support for UUID instantiation through 16 byte strings such as `b'\x12\x34\x56\x78' * 4`. This was done to support `BINARY(16)` columns in sqlalchemy, [#1541](https://github.com/samuelcolvin/pydantic/issues/1541) by [@shawnwall](https://github.com/shawnwall) -* Add a test assertion that `default_factory` can return a singleton, [#1523](https://github.com/samuelcolvin/pydantic/issues/1523) by [@therefromhere](https://github.com/therefromhere) -* Add `NameEmail.__eq__` so duplicate `NameEmail` instances are evaluated as equal, [#1514](https://github.com/samuelcolvin/pydantic/issues/1514) by [@stephen-bunn](https://github.com/stephen-bunn) -* Add datamodel-code-generator link in pydantic document site, [#1500](https://github.com/samuelcolvin/pydantic/issues/1500) by [@koxudaxi](https://github.com/koxudaxi) -* Added a "Discussion of Pydantic" section to the documentation, with a link to "Pydantic Introduction" video by Alexander Hultnér, [#1499](https://github.com/samuelcolvin/pydantic/issues/1499) by [@hultner](https://github.com/hultner) -* Avoid some side effects of `default_factory` by calling it only once - if possible and by not setting a default value in the schema, [#1491](https://github.com/samuelcolvin/pydantic/issues/1491) by [@PrettyWood](https://github.com/PrettyWood) -* Added docs about dumping dataclasses to JSON, [#1487](https://github.com/samuelcolvin/pydantic/issues/1487) by [@mikegrima](https://github.com/mikegrima) -* Make `BaseModel.__signature__` class-only, so getting `__signature__` from model instance will raise `AttributeError`, [#1466](https://github.com/samuelcolvin/pydantic/issues/1466) by [@MrMrRobat](https://github.com/MrMrRobat) -* include `'format': 'password'` in the schema for secret types, [#1424](https://github.com/samuelcolvin/pydantic/issues/1424) by [@atheuz](https://github.com/atheuz) -* Modify schema constraints on `ConstrainedFloat` so that `exclusiveMinimum` and - minimum are not included in the schema if they are equal to `-math.inf` and - `exclusiveMaximum` and `maximum` are not included if they are equal to `math.inf`, [#1417](https://github.com/samuelcolvin/pydantic/issues/1417) by [@vdwees](https://github.com/vdwees) -* Squash internal `__root__` dicts in `.dict()` (and, by extension, in `.json()`), [#1414](https://github.com/samuelcolvin/pydantic/issues/1414) by [@patrickkwang](https://github.com/patrickkwang) -* Move `const` validator to post-validators so it validates the parsed value, [#1410](https://github.com/samuelcolvin/pydantic/issues/1410) by [@selimb](https://github.com/selimb) -* Fix model validation to handle nested literals, e.g. `Literal['foo', Literal['bar']]`, [#1364](https://github.com/samuelcolvin/pydantic/issues/1364) by [@DBCerigo](https://github.com/DBCerigo) -* Remove `user_required = True` from `RedisDsn`, neither user nor password are required, [#1275](https://github.com/samuelcolvin/pydantic/issues/1275) by [@samuelcolvin](https://github.com/samuelcolvin) -* Remove extra `allOf` from schema for fields with `Union` and custom `Field`, [#1209](https://github.com/samuelcolvin/pydantic/issues/1209) by [@mostaphaRoudsari](https://github.com/mostaphaRoudsari) -* Updates OpenAPI schema generation to output all enums as separate models. - Instead of inlining the enum values in the model schema, models now use a `$ref` - property to point to the enum definition, [#1173](https://github.com/samuelcolvin/pydantic/issues/1173) by [@calvinwyoung](https://github.com/calvinwyoung) - -## v1.5.1 (2020-04-23) - -* Signature generation with `extra: allow` never uses a field name, [#1418](https://github.com/samuelcolvin/pydantic/issues/1418) by [@prettywood](https://github.com/prettywood) -* Avoid mutating `Field` default value, [#1412](https://github.com/samuelcolvin/pydantic/issues/1412) by [@prettywood](https://github.com/prettywood) - -## v1.5 (2020-04-18) - -* Make includes/excludes arguments for `.dict()`, `._iter()`, ..., immutable, [#1404](https://github.com/samuelcolvin/pydantic/issues/1404) by [@AlexECX](https://github.com/AlexECX) -* Always use a field's real name with includes/excludes in `model._iter()`, regardless of `by_alias`, [#1397](https://github.com/samuelcolvin/pydantic/issues/1397) by [@AlexECX](https://github.com/AlexECX) -* Update constr regex example to include start and end lines, [#1396](https://github.com/samuelcolvin/pydantic/issues/1396) by [@lmcnearney](https://github.com/lmcnearney) -* Confirm that shallow `model.copy()` does make a shallow copy of attributes, [#1383](https://github.com/samuelcolvin/pydantic/issues/1383) by [@samuelcolvin](https://github.com/samuelcolvin) -* Renaming `model_name` argument of `main.create_model()` to `__model_name` to allow using `model_name` as a field name, [#1367](https://github.com/samuelcolvin/pydantic/issues/1367) by [@kittipatv](https://github.com/kittipatv) -* Replace raising of exception to silent passing for non-Var attributes in mypy plugin, [#1345](https://github.com/samuelcolvin/pydantic/issues/1345) by [@b0g3r](https://github.com/b0g3r) -* Remove `typing_extensions` dependency for python 3.8, [#1342](https://github.com/samuelcolvin/pydantic/issues/1342) by [@prettywood](https://github.com/prettywood) -* Make `SecretStr` and `SecretBytes` initialization idempotent, [#1330](https://github.com/samuelcolvin/pydantic/issues/1330) by [@atheuz](https://github.com/atheuz) -* document making secret types dumpable using the json method, [#1328](https://github.com/samuelcolvin/pydantic/issues/1328) by [@atheuz](https://github.com/atheuz) -* Move all testing and build to github actions, add windows and macos binaries, - thank you [@StephenBrown2](https://github.com/StephenBrown2) for much help, [#1326](https://github.com/samuelcolvin/pydantic/issues/1326) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix card number length check in `PaymentCardNumber`, `PaymentCardBrand` now inherits from `str`, [#1317](https://github.com/samuelcolvin/pydantic/issues/1317) by [@samuelcolvin](https://github.com/samuelcolvin) -* Have `BaseModel` inherit from `Representation` to make mypy happy when overriding `__str__`, [#1310](https://github.com/samuelcolvin/pydantic/issues/1310) by [@FuegoFro](https://github.com/FuegoFro) -* Allow `None` as input to all optional list fields, [#1307](https://github.com/samuelcolvin/pydantic/issues/1307) by [@prettywood](https://github.com/prettywood) -* Add `datetime` field to `default_factory` example, [#1301](https://github.com/samuelcolvin/pydantic/issues/1301) by [@StephenBrown2](https://github.com/StephenBrown2) -* Allow subclasses of known types to be encoded with superclass encoder, [#1291](https://github.com/samuelcolvin/pydantic/issues/1291) by [@StephenBrown2](https://github.com/StephenBrown2) -* Exclude exported fields from all elements of a list/tuple of submodels/dicts with `'__all__'`, [#1286](https://github.com/samuelcolvin/pydantic/issues/1286) by [@masalim2](https://github.com/masalim2) -* Add pydantic.color.Color objects as available input for Color fields, [#1258](https://github.com/samuelcolvin/pydantic/issues/1258) by [@leosussan](https://github.com/leosussan) -* In examples, type nullable fields as `Optional`, so that these are valid mypy annotations, [#1248](https://github.com/samuelcolvin/pydantic/issues/1248) by [@kokes](https://github.com/kokes) -* Make `pattern_validator()` accept pre-compiled `Pattern` objects. Fix `str_validator()` return type to `str`, [#1237](https://github.com/samuelcolvin/pydantic/issues/1237) by [@adamgreg](https://github.com/adamgreg) -* Document how to manage Generics and inheritance, [#1229](https://github.com/samuelcolvin/pydantic/issues/1229) by [@esadruhn](https://github.com/esadruhn) -* `update_forward_refs()` method of BaseModel now copies `__dict__` of class module instead of modyfying it, [#1228](https://github.com/samuelcolvin/pydantic/issues/1228) by [@paul-ilyin](https://github.com/paul-ilyin) -* Support instance methods and class methods with `@validate_arguments`, [#1222](https://github.com/samuelcolvin/pydantic/issues/1222) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add `default_factory` argument to `Field` to create a dynamic default value by passing a zero-argument callable, [#1210](https://github.com/samuelcolvin/pydantic/issues/1210) by [@prettywood](https://github.com/prettywood) -* add support for `NewType` of `List`, `Optional`, etc, [#1207](https://github.com/samuelcolvin/pydantic/issues/1207) by [@Kazy](https://github.com/Kazy) -* fix mypy signature for `root_validator`, [#1192](https://github.com/samuelcolvin/pydantic/issues/1192) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fixed parsing of nested 'custom root type' models, [#1190](https://github.com/samuelcolvin/pydantic/issues/1190) by [@Shados](https://github.com/Shados) -* Add `validate_arguments` function decorator which checks the arguments to a function matches type annotations, [#1179](https://github.com/samuelcolvin/pydantic/issues/1179) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add `__signature__` to models, [#1034](https://github.com/samuelcolvin/pydantic/issues/1034) by [@MrMrRobat](https://github.com/MrMrRobat) -* Refactor `._iter()` method, 10x speed boost for `dict(model)`, [#1017](https://github.com/samuelcolvin/pydantic/issues/1017) by [@MrMrRobat](https://github.com/MrMrRobat) - -## v1.4 (2020-01-24) - -* **Breaking Change:** alias precedence logic changed so aliases on a field always take priority over - an alias from `alias_generator` to avoid buggy/unexpected behaviour, - see [here](https://pydantic-docs.helpmanual.io/usage/model_config/#alias-precedence) for details, [#1178](https://github.com/samuelcolvin/pydantic/issues/1178) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add support for unicode and punycode in TLDs, [#1182](https://github.com/samuelcolvin/pydantic/issues/1182) by [@jamescurtin](https://github.com/jamescurtin) -* Fix `cls` argument in validators during assignment, [#1172](https://github.com/samuelcolvin/pydantic/issues/1172) by [@samuelcolvin](https://github.com/samuelcolvin) -* completing Luhn algorithm for `PaymentCardNumber`, [#1166](https://github.com/samuelcolvin/pydantic/issues/1166) by [@cuencandres](https://github.com/cuencandres) -* add support for generics that implement `__get_validators__` like a custom data type, [#1159](https://github.com/samuelcolvin/pydantic/issues/1159) by [@tiangolo](https://github.com/tiangolo) -* add support for infinite generators with `Iterable`, [#1152](https://github.com/samuelcolvin/pydantic/issues/1152) by [@tiangolo](https://github.com/tiangolo) -* fix `url_regex` to accept schemas with `+`, `-` and `.` after the first character, [#1142](https://github.com/samuelcolvin/pydantic/issues/1142) by [@samuelcolvin](https://github.com/samuelcolvin) -* move `version_info()` to `version.py`, suggest its use in issues, [#1138](https://github.com/samuelcolvin/pydantic/issues/1138) by [@samuelcolvin](https://github.com/samuelcolvin) -* Improve pydantic import time by roughly 50% by deferring some module loading and regex compilation, [#1127](https://github.com/samuelcolvin/pydantic/issues/1127) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix `EmailStr` and `NameEmail` to accept instances of themselves in cython, [#1126](https://github.com/samuelcolvin/pydantic/issues/1126) by [@koxudaxi](https://github.com/koxudaxi) -* Pass model class to the `Config.schema_extra` callable, [#1125](https://github.com/samuelcolvin/pydantic/issues/1125) by [@therefromhere](https://github.com/therefromhere) -* Fix regex for username and password in URLs, [#1115](https://github.com/samuelcolvin/pydantic/issues/1115) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add support for nested generic models, [#1104](https://github.com/samuelcolvin/pydantic/issues/1104) by [@dmontagu](https://github.com/dmontagu) -* add `__all__` to `__init__.py` to prevent "implicit reexport" errors from mypy, [#1072](https://github.com/samuelcolvin/pydantic/issues/1072) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add support for using "dotenv" files with `BaseSettings`, [#1011](https://github.com/samuelcolvin/pydantic/issues/1011) by [@acnebs](https://github.com/acnebs) - -## v1.3 (2019-12-21) - -* Change `schema` and `schema_model` to handle dataclasses by using their `__pydantic_model__` feature, [#792](https://github.com/samuelcolvin/pydantic/issues/792) by [@aviramha](https://github.com/aviramha) -* Added option for `root_validator` to be skipped if values validation fails using keyword `skip_on_failure=True`, [#1049](https://github.com/samuelcolvin/pydantic/issues/1049) by [@aviramha](https://github.com/aviramha) -* Allow `Config.schema_extra` to be a callable so that the generated schema can be post-processed, [#1054](https://github.com/samuelcolvin/pydantic/issues/1054) by [@selimb](https://github.com/selimb) -* Update mypy to version 0.750, [#1057](https://github.com/samuelcolvin/pydantic/issues/1057) by [@dmontagu](https://github.com/dmontagu) -* Trick Cython into allowing str subclassing, [#1061](https://github.com/samuelcolvin/pydantic/issues/1061) by [@skewty](https://github.com/skewty) -* Prevent type attributes being added to schema unless the attribute `__schema_attributes__` is `True`, [#1064](https://github.com/samuelcolvin/pydantic/issues/1064) by [@samuelcolvin](https://github.com/samuelcolvin) -* Change `BaseModel.parse_file` to use `Config.json_loads`, [#1067](https://github.com/samuelcolvin/pydantic/issues/1067) by [@kierandarcy](https://github.com/kierandarcy) -* Fix for optional `Json` fields, [#1073](https://github.com/samuelcolvin/pydantic/issues/1073) by [@volker48](https://github.com/volker48) -* Change the default number of threads used when compiling with cython to one, - allow override via the `CYTHON_NTHREADS` environment variable, [#1074](https://github.com/samuelcolvin/pydantic/issues/1074) by [@samuelcolvin](https://github.com/samuelcolvin) -* Run FastAPI tests during Pydantic's CI tests, [#1075](https://github.com/samuelcolvin/pydantic/issues/1075) by [@tiangolo](https://github.com/tiangolo) -* My mypy strictness constraints, and associated tweaks to type annotations, [#1077](https://github.com/samuelcolvin/pydantic/issues/1077) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add `__eq__` to SecretStr and SecretBytes to allow "value equals", [#1079](https://github.com/samuelcolvin/pydantic/issues/1079) by [@sbv-trueenergy](https://github.com/sbv-trueenergy) -* Fix schema generation for nested None case, [#1088](https://github.com/samuelcolvin/pydantic/issues/1088) by [@lutostag](https://github.com/lutostag) -* Consistent checks for sequence like objects, [#1090](https://github.com/samuelcolvin/pydantic/issues/1090) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix `Config` inheritance on `BaseSettings` when used with `env_prefix`, [#1091](https://github.com/samuelcolvin/pydantic/issues/1091) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix for `__modify_schema__` when it conflicted with `field_class_to_schema*`, [#1102](https://github.com/samuelcolvin/pydantic/issues/1102) by [@samuelcolvin](https://github.com/samuelcolvin) -* docs: Fix explanation of case sensitive environment variable names when populating `BaseSettings` subclass attributes, [#1105](https://github.com/samuelcolvin/pydantic/issues/1105) by [@tribals](https://github.com/tribals) -* Rename django-rest-framework benchmark in documentation, [#1119](https://github.com/samuelcolvin/pydantic/issues/1119) by [@frankie567](https://github.com/frankie567) - -## v1.2 (2019-11-28) - -* **Possible Breaking Change:** Add support for required `Optional` with `name: Optional[AnyType] = Field(...)` - and refactor `ModelField` creation to preserve `required` parameter value, [#1031](https://github.com/samuelcolvin/pydantic/issues/1031) by [@tiangolo](https://github.com/tiangolo); - see [here](https://pydantic-docs.helpmanual.io/usage/models/#required-optional-fields) for details -* Add benchmarks for `cattrs`, [#513](https://github.com/samuelcolvin/pydantic/issues/513) by [@sebastianmika](https://github.com/sebastianmika) -* Add `exclude_none` option to `dict()` and friends, [#587](https://github.com/samuelcolvin/pydantic/issues/587) by [@niknetniko](https://github.com/niknetniko) -* Add benchmarks for `valideer`, [#670](https://github.com/samuelcolvin/pydantic/issues/670) by [@gsakkis](https://github.com/gsakkis) -* Add `parse_obj_as` and `parse_file_as` functions for ad-hoc parsing of data into arbitrary pydantic-compatible types, [#934](https://github.com/samuelcolvin/pydantic/issues/934) by [@dmontagu](https://github.com/dmontagu) -* Add `allow_reuse` argument to validators, thus allowing validator reuse, [#940](https://github.com/samuelcolvin/pydantic/issues/940) by [@dmontagu](https://github.com/dmontagu) -* Add support for mapping types for custom root models, [#958](https://github.com/samuelcolvin/pydantic/issues/958) by [@dmontagu](https://github.com/dmontagu) -* Mypy plugin support for dataclasses, [#966](https://github.com/samuelcolvin/pydantic/issues/966) by [@koxudaxi](https://github.com/koxudaxi) -* Add support for dataclasses default factory, [#968](https://github.com/samuelcolvin/pydantic/issues/968) by [@ahirner](https://github.com/ahirner) -* Add a `ByteSize` type for converting byte string (`1GB`) to plain bytes, [#977](https://github.com/samuelcolvin/pydantic/issues/977) by [@dgasmith](https://github.com/dgasmith) -* Fix mypy complaint about `@root_validator(pre=True)`, [#984](https://github.com/samuelcolvin/pydantic/issues/984) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add manylinux binaries for python 3.8 to pypi, also support manylinux2010, [#994](https://github.com/samuelcolvin/pydantic/issues/994) by [@samuelcolvin](https://github.com/samuelcolvin) -* Adds ByteSize conversion to another unit, [#995](https://github.com/samuelcolvin/pydantic/issues/995) by [@dgasmith](https://github.com/dgasmith) -* Fix `__str__` and `__repr__` inheritance for models, [#1022](https://github.com/samuelcolvin/pydantic/issues/1022) by [@samuelcolvin](https://github.com/samuelcolvin) -* add testimonials section to docs, [#1025](https://github.com/samuelcolvin/pydantic/issues/1025) by [@sullivancolin](https://github.com/sullivancolin) -* Add support for `typing.Literal` for Python 3.8, [#1026](https://github.com/samuelcolvin/pydantic/issues/1026) by [@dmontagu](https://github.com/dmontagu) - -## v1.1.1 (2019-11-20) - -* Fix bug where use of complex fields on sub-models could cause fields to be incorrectly configured, [#1015](https://github.com/samuelcolvin/pydantic/issues/1015) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v1.1 (2019-11-07) - -* Add a mypy plugin for type checking `BaseModel.__init__` and more, [#722](https://github.com/samuelcolvin/pydantic/issues/722) by [@dmontagu](https://github.com/dmontagu) -* Change return type typehint for `GenericModel.__class_getitem__` to prevent PyCharm warnings, [#936](https://github.com/samuelcolvin/pydantic/issues/936) by [@dmontagu](https://github.com/dmontagu) -* Fix usage of `Any` to allow `None`, also support `TypeVar` thus allowing use of un-parameterised collection types - e.g. `Dict` and `List`, [#962](https://github.com/samuelcolvin/pydantic/issues/962) by [@samuelcolvin](https://github.com/samuelcolvin) -* Set `FieldInfo` on subfields to fix schema generation for complex nested types, [#965](https://github.com/samuelcolvin/pydantic/issues/965) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v1.0 (2019-10-23) - -* **Breaking Change:** deprecate the `Model.fields` property, use `Model.__fields__` instead, [#883](https://github.com/samuelcolvin/pydantic/issues/883) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking Change:** Change the precedence of aliases so child model aliases override parent aliases, - including using `alias_generator`, [#904](https://github.com/samuelcolvin/pydantic/issues/904) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking change:** Rename `skip_defaults` to `exclude_unset`, and add ability to exclude actual defaults, [#915](https://github.com/samuelcolvin/pydantic/issues/915) by [@dmontagu](https://github.com/dmontagu) -* Add `**kwargs` to `pydantic.main.ModelMetaclass.__new__` so `__init_subclass__` can take custom parameters on extended - `BaseModel` classes, [#867](https://github.com/samuelcolvin/pydantic/issues/867) by [@retnikt](https://github.com/retnikt) -* Fix field of a type that has a default value, [#880](https://github.com/samuelcolvin/pydantic/issues/880) by [@koxudaxi](https://github.com/koxudaxi) -* Use `FutureWarning` instead of `DeprecationWarning` when `alias` instead of `env` is used for settings models, [#881](https://github.com/samuelcolvin/pydantic/issues/881) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix issue with `BaseSettings` inheritance and `alias` getting set to `None`, [#882](https://github.com/samuelcolvin/pydantic/issues/882) by [@samuelcolvin](https://github.com/samuelcolvin) -* Modify `__repr__` and `__str__` methods to be consistent across all public classes, add `__pretty__` to support - python-devtools, [#884](https://github.com/samuelcolvin/pydantic/issues/884) by [@samuelcolvin](https://github.com/samuelcolvin) -* deprecation warning for `case_insensitive` on `BaseSettings` config, [#885](https://github.com/samuelcolvin/pydantic/issues/885) by [@samuelcolvin](https://github.com/samuelcolvin) -* For `BaseSettings` merge environment variables and in-code values recursively, as long as they create a valid object - when merged together, to allow splitting init arguments, [#888](https://github.com/samuelcolvin/pydantic/issues/888) by [@idmitrievsky](https://github.com/idmitrievsky) -* change secret types example, [#890](https://github.com/samuelcolvin/pydantic/issues/890) by [@ashears](https://github.com/ashears) -* Change the signature of `Model.construct()` to be more user-friendly, document `construct()` usage, [#898](https://github.com/samuelcolvin/pydantic/issues/898) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add example for the `construct()` method, [#907](https://github.com/samuelcolvin/pydantic/issues/907) by [@ashears](https://github.com/ashears) -* Improve use of `Field` constraints on complex types, raise an error if constraints are not enforceable, - also support tuples with an ellipsis `Tuple[X, ...]`, `Sequence` and `FrozenSet` in schema, [#909](https://github.com/samuelcolvin/pydantic/issues/909) by [@samuelcolvin](https://github.com/samuelcolvin) -* update docs for bool missing valid value, [#911](https://github.com/samuelcolvin/pydantic/issues/911) by [@trim21](https://github.com/trim21) -* Better `str`/`repr` logic for `ModelField`, [#912](https://github.com/samuelcolvin/pydantic/issues/912) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix `ConstrainedList`, update schema generation to reflect `min_items` and `max_items` `Field()` arguments, [#917](https://github.com/samuelcolvin/pydantic/issues/917) by [@samuelcolvin](https://github.com/samuelcolvin) -* Allow abstracts sets (eg. dict keys) in the `include` and `exclude` arguments of `dict()`, [#921](https://github.com/samuelcolvin/pydantic/issues/921) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix JSON serialization errors on `ValidationError.json()` by using `pydantic_encoder`, [#922](https://github.com/samuelcolvin/pydantic/issues/922) by [@samuelcolvin](https://github.com/samuelcolvin) -* Clarify usage of `remove_untouched`, improve error message for types with no validators, [#926](https://github.com/samuelcolvin/pydantic/issues/926) by [@retnikt](https://github.com/retnikt) - -## v1.0b2 (2019-10-07) - -* Mark `StrictBool` typecheck as `bool` to allow for default values without mypy errors, [#690](https://github.com/samuelcolvin/pydantic/issues/690) by [@dmontagu](https://github.com/dmontagu) -* Transfer the documentation build from sphinx to mkdocs, re-write much of the documentation, [#856](https://github.com/samuelcolvin/pydantic/issues/856) by [@samuelcolvin](https://github.com/samuelcolvin) -* Add support for custom naming schemes for `GenericModel` subclasses, [#859](https://github.com/samuelcolvin/pydantic/issues/859) by [@dmontagu](https://github.com/dmontagu) -* Add `if TYPE_CHECKING:` to the excluded lines for test coverage, [#874](https://github.com/samuelcolvin/pydantic/issues/874) by [@dmontagu](https://github.com/dmontagu) -* Rename `allow_population_by_alias` to `allow_population_by_field_name`, remove unnecessary warning about it, [#875](https://github.com/samuelcolvin/pydantic/issues/875) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v1.0b1 (2019-10-01) - -* **Breaking Change:** rename `Schema` to `Field`, make it a function to placate mypy, [#577](https://github.com/samuelcolvin/pydantic/issues/577) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking Change:** modify parsing behavior for `bool`, [#617](https://github.com/samuelcolvin/pydantic/issues/617) by [@dmontagu](https://github.com/dmontagu) -* **Breaking Change:** `get_validators` is no longer recognised, use `__get_validators__`. - `Config.ignore_extra` and `Config.allow_extra` are no longer recognised, use `Config.extra`, [#720](https://github.com/samuelcolvin/pydantic/issues/720) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking Change:** modify default config settings for `BaseSettings`; `case_insensitive` renamed to `case_sensitive`, - default changed to `case_sensitive = False`, `env_prefix` default changed to `''` - e.g. no prefix, [#721](https://github.com/samuelcolvin/pydantic/issues/721) by [@dmontagu](https://github.com/dmontagu) -* **Breaking change:** Implement `root_validator` and rename root errors from `__obj__` to `__root__`, [#729](https://github.com/samuelcolvin/pydantic/issues/729) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking Change:** alter the behaviour of `dict(model)` so that sub-models are nolonger - converted to dictionaries, [#733](https://github.com/samuelcolvin/pydantic/issues/733) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking change:** Added `initvars` support to `post_init_post_parse`, [#748](https://github.com/samuelcolvin/pydantic/issues/748) by [@Raphael-C-Almeida](https://github.com/Raphael-C-Almeida) -* **Breaking Change:** Make `BaseModel.json()` only serialize the `__root__` key for models with custom root, [#752](https://github.com/samuelcolvin/pydantic/issues/752) by [@dmontagu](https://github.com/dmontagu) -* **Breaking Change:** complete rewrite of `URL` parsing logic, [#755](https://github.com/samuelcolvin/pydantic/issues/755) by [@samuelcolvin](https://github.com/samuelcolvin) -* **Breaking Change:** preserve superclass annotations for field-determination when not provided in subclass, [#757](https://github.com/samuelcolvin/pydantic/issues/757) by [@dmontagu](https://github.com/dmontagu) -* **Breaking Change:** `BaseSettings` now uses the special `env` settings to define which environment variables to - read, not aliases, [#847](https://github.com/samuelcolvin/pydantic/issues/847) by [@samuelcolvin](https://github.com/samuelcolvin) -* add support for `assert` statements inside validators, [#653](https://github.com/samuelcolvin/pydantic/issues/653) by [@abdusco](https://github.com/abdusco) -* Update documentation to specify the use of `pydantic.dataclasses.dataclass` and subclassing `pydantic.BaseModel`, [#710](https://github.com/samuelcolvin/pydantic/issues/710) by [@maddosaurus](https://github.com/maddosaurus) -* Allow custom JSON decoding and encoding via `json_loads` and `json_dumps` `Config` properties, [#714](https://github.com/samuelcolvin/pydantic/issues/714) by [@samuelcolvin](https://github.com/samuelcolvin) -* make all annotated fields occur in the order declared, [#715](https://github.com/samuelcolvin/pydantic/issues/715) by [@dmontagu](https://github.com/dmontagu) -* use pytest to test `mypy` integration, [#735](https://github.com/samuelcolvin/pydantic/issues/735) by [@dmontagu](https://github.com/dmontagu) -* add `__repr__` method to `ErrorWrapper`, [#738](https://github.com/samuelcolvin/pydantic/issues/738) by [@samuelcolvin](https://github.com/samuelcolvin) -* Added support for `FrozenSet` members in dataclasses, and a better error when attempting to use types from the `typing` module that are not supported by Pydantic, [#745](https://github.com/samuelcolvin/pydantic/issues/745) by [@djpetti](https://github.com/djpetti) -* add documentation for Pycharm Plugin, [#750](https://github.com/samuelcolvin/pydantic/issues/750) by [@koxudaxi](https://github.com/koxudaxi) -* fix broken examples in the docs, [#753](https://github.com/samuelcolvin/pydantic/issues/753) by [@dmontagu](https://github.com/dmontagu) -* moving typing related objects into `pydantic.typing`, [#761](https://github.com/samuelcolvin/pydantic/issues/761) by [@samuelcolvin](https://github.com/samuelcolvin) -* Minor performance improvements to `ErrorWrapper`, `ValidationError` and datetime parsing, [#763](https://github.com/samuelcolvin/pydantic/issues/763) by [@samuelcolvin](https://github.com/samuelcolvin) -* Improvements to `datetime`/`date`/`time`/`timedelta` types: more descriptive errors, - change errors to `value_error` not `type_error`, support bytes, [#766](https://github.com/samuelcolvin/pydantic/issues/766) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix error messages for `Literal` types with multiple allowed values, [#770](https://github.com/samuelcolvin/pydantic/issues/770) by [@dmontagu](https://github.com/dmontagu) -* Improved auto-generated `title` field in JSON schema by converting underscore to space, [#772](https://github.com/samuelcolvin/pydantic/issues/772) by [@skewty](https://github.com/skewty) -* support `mypy --no-implicit-reexport` for dataclasses, also respect `--no-implicit-reexport` in pydantic itself, [#783](https://github.com/samuelcolvin/pydantic/issues/783) by [@samuelcolvin](https://github.com/samuelcolvin) -* add the `PaymentCardNumber` type, [#790](https://github.com/samuelcolvin/pydantic/issues/790) by [@matin](https://github.com/matin) -* Fix const validations for lists, [#794](https://github.com/samuelcolvin/pydantic/issues/794) by [@hmvp](https://github.com/hmvp) -* Set `additionalProperties` to false in schema for models with extra fields disallowed, [#796](https://github.com/samuelcolvin/pydantic/issues/796) by [@Code0x58](https://github.com/Code0x58) -* `EmailStr` validation method now returns local part case-sensitive per RFC 5321, [#798](https://github.com/samuelcolvin/pydantic/issues/798) by [@henriklindgren](https://github.com/henriklindgren) -* Added ability to validate strictness to `ConstrainedFloat`, `ConstrainedInt` and `ConstrainedStr` and added - `StrictFloat` and `StrictInt` classes, [#799](https://github.com/samuelcolvin/pydantic/issues/799) by [@DerRidda](https://github.com/DerRidda) -* Improve handling of `None` and `Optional`, replace `whole` with `each_item` (inverse meaning, default `False`) - on validators, [#803](https://github.com/samuelcolvin/pydantic/issues/803) by [@samuelcolvin](https://github.com/samuelcolvin) -* add support for `Type[T]` type hints, [#807](https://github.com/samuelcolvin/pydantic/issues/807) by [@timonbimon](https://github.com/timonbimon) -* Performance improvements from removing `change_exceptions`, change how pydantic error are constructed, [#819](https://github.com/samuelcolvin/pydantic/issues/819) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix the error message arising when a `BaseModel`-type model field causes a `ValidationError` during parsing, [#820](https://github.com/samuelcolvin/pydantic/issues/820) by [@dmontagu](https://github.com/dmontagu) -* allow `getter_dict` on `Config`, modify `GetterDict` to be more like a `Mapping` object and thus easier to work with, [#821](https://github.com/samuelcolvin/pydantic/issues/821) by [@samuelcolvin](https://github.com/samuelcolvin) -* Only check `TypeVar` param on base `GenericModel` class, [#842](https://github.com/samuelcolvin/pydantic/issues/842) by [@zpencerq](https://github.com/zpencerq) -* rename `Model._schema_cache` -> `Model.__schema_cache__`, `Model._json_encoder` -> `Model.__json_encoder__`, - `Model._custom_root_type` -> `Model.__custom_root_type__`, [#851](https://github.com/samuelcolvin/pydantic/issues/851) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.32.2 (2019-08-17) - -(Docs are available [here](https://5d584fcca7c9b70007d1c997--pydantic-docs.netlify.com)) - -* fix `__post_init__` usage with dataclass inheritance, fix [#739](https://github.com/samuelcolvin/pydantic/issues/739) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix required fields validation on GenericModels classes, [#742](https://github.com/samuelcolvin/pydantic/issues/742) by [@amitbl](https://github.com/amitbl) -* fix defining custom `Schema` on `GenericModel` fields, [#754](https://github.com/samuelcolvin/pydantic/issues/754) by [@amitbl](https://github.com/amitbl) - -## v0.32.1 (2019-08-08) - -* do not validate extra fields when `validate_assignment` is on, [#724](https://github.com/samuelcolvin/pydantic/issues/724) by [@YaraslauZhylko](https://github.com/YaraslauZhylko) - -## v0.32 (2019-08-06) - -* add model name to `ValidationError` error message, [#676](https://github.com/samuelcolvin/pydantic/issues/676) by [@dmontagu](https://github.com/dmontagu) -* **breaking change**: remove `__getattr__` and rename `__values__` to `__dict__` on `BaseModel`, - deprecation warning on use `__values__` attr, attributes access speed increased up to 14 times, [#712](https://github.com/samuelcolvin/pydantic/issues/712) by [@MrMrRobat](https://github.com/MrMrRobat) -* support `ForwardRef` (without self-referencing annotations) in Python 3.6, [#706](https://github.com/samuelcolvin/pydantic/issues/706) by [@koxudaxi](https://github.com/koxudaxi) -* implement `schema_extra` in `Config` sub-class, [#663](https://github.com/samuelcolvin/pydantic/issues/663) by [@tiangolo](https://github.com/tiangolo) - -## v0.31.1 (2019-07-31) - -* fix json generation for `EnumError`, [#697](https://github.com/samuelcolvin/pydantic/issues/697) by [@dmontagu](https://github.com/dmontagu) -* update numerous dependencies - -## v0.31 (2019-07-24) - -* better support for floating point `multiple_of` values, [#652](https://github.com/samuelcolvin/pydantic/issues/652) by [@justindujardin](https://github.com/justindujardin) -* fix schema generation for `NewType` and `Literal`, [#649](https://github.com/samuelcolvin/pydantic/issues/649) by [@dmontagu](https://github.com/dmontagu) -* fix `alias_generator` and field config conflict, [#645](https://github.com/samuelcolvin/pydantic/issues/645) by [@gmetzker](https://github.com/gmetzker) and [#658](https://github.com/samuelcolvin/pydantic/issues/658) by [@MrMrRobat](https://github.com/MrMrRobat) -* more detailed message for `EnumError`, [#673](https://github.com/samuelcolvin/pydantic/issues/673) by [@dmontagu](https://github.com/dmontagu) -* add advanced exclude support for `dict`, `json` and `copy`, [#648](https://github.com/samuelcolvin/pydantic/issues/648) by [@MrMrRobat](https://github.com/MrMrRobat) -* fix bug in `GenericModel` for models with concrete parameterized fields, [#672](https://github.com/samuelcolvin/pydantic/issues/672) by [@dmontagu](https://github.com/dmontagu) -* add documentation for `Literal` type, [#651](https://github.com/samuelcolvin/pydantic/issues/651) by [@dmontagu](https://github.com/dmontagu) -* add `Config.keep_untouched` for custom descriptors support, [#679](https://github.com/samuelcolvin/pydantic/issues/679) by [@MrMrRobat](https://github.com/MrMrRobat) -* use `inspect.cleandoc` internally to get model description, [#657](https://github.com/samuelcolvin/pydantic/issues/657) by [@tiangolo](https://github.com/tiangolo) -* add `Color` to schema generation, by [@euri10](https://github.com/euri10) -* add documentation for Literal type, [#651](https://github.com/samuelcolvin/pydantic/issues/651) by [@dmontagu](https://github.com/dmontagu) - -## v0.30.1 (2019-07-15) - -* fix so nested classes which inherit and change `__init__` are correctly processed while still allowing `self` as a - parameter, [#644](https://github.com/samuelcolvin/pydantic/issues/644) by [@lnaden](https://github.com/lnaden) and [@dgasmith](https://github.com/dgasmith) - -## v0.30 (2019-07-07) - -* enforce single quotes in code, [#612](https://github.com/samuelcolvin/pydantic/issues/612) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix infinite recursion with dataclass inheritance and `__post_init__`, [#606](https://github.com/samuelcolvin/pydantic/issues/606) by [@Hanaasagi](https://github.com/Hanaasagi) -* fix default values for `GenericModel`, [#610](https://github.com/samuelcolvin/pydantic/issues/610) by [@dmontagu](https://github.com/dmontagu) -* clarify that self-referencing models require python 3.7+, [#616](https://github.com/samuelcolvin/pydantic/issues/616) by [@vlcinsky](https://github.com/vlcinsky) -* fix truncate for types, [#611](https://github.com/samuelcolvin/pydantic/issues/611) by [@dmontagu](https://github.com/dmontagu) -* add `alias_generator` support, [#622](https://github.com/samuelcolvin/pydantic/issues/622) by [@MrMrRobat](https://github.com/MrMrRobat) -* fix unparameterized generic type schema generation, [#625](https://github.com/samuelcolvin/pydantic/issues/625) by [@dmontagu](https://github.com/dmontagu) -* fix schema generation with multiple/circular references to the same model, [#621](https://github.com/samuelcolvin/pydantic/issues/621) by [@tiangolo](https://github.com/tiangolo) and [@wongpat](https://github.com/wongpat) -* support custom root types, [#628](https://github.com/samuelcolvin/pydantic/issues/628) by [@koxudaxi](https://github.com/koxudaxi) -* support `self` as a field name in `parse_obj`, [#632](https://github.com/samuelcolvin/pydantic/issues/632) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.29 (2019-06-19) - -* support dataclasses.InitVar, [#592](https://github.com/samuelcolvin/pydantic/issues/592) by [@pfrederiks](https://github.com/pfrederiks) -* Updated documentation to elucidate the usage of `Union` when defining multiple types under an attribute's - annotation and showcase how the type-order can affect marshalling of provided values, [#594](https://github.com/samuelcolvin/pydantic/issues/594) by [@somada141](https://github.com/somada141) -* add `conlist` type, [#583](https://github.com/samuelcolvin/pydantic/issues/583) by [@hmvp](https://github.com/hmvp) -* add support for generics, [#595](https://github.com/samuelcolvin/pydantic/issues/595) by [@dmontagu](https://github.com/dmontagu) - -## v0.28 (2019-06-06) - -* fix support for JSON Schema generation when using models with circular references in Python 3.7, [#572](https://github.com/samuelcolvin/pydantic/issues/572) by [@tiangolo](https://github.com/tiangolo) -* support `__post_init_post_parse__` on dataclasses, [#567](https://github.com/samuelcolvin/pydantic/issues/567) by [@sevaho](https://github.com/sevaho) -* allow dumping dataclasses to JSON, [#575](https://github.com/samuelcolvin/pydantic/issues/575) by [@samuelcolvin](https://github.com/samuelcolvin) and [@DanielOberg](https://github.com/DanielOberg) -* ORM mode, [#562](https://github.com/samuelcolvin/pydantic/issues/562) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix `pydantic.compiled` on ipython, [#573](https://github.com/samuelcolvin/pydantic/issues/573) by [@dmontagu](https://github.com/dmontagu) and [@samuelcolvin](https://github.com/samuelcolvin) -* add `StrictBool` type, [#579](https://github.com/samuelcolvin/pydantic/issues/579) by [@cazgp](https://github.com/cazgp) - -## v0.27 (2019-05-30) - -* **breaking change** `_pydantic_post_init` to execute dataclass' original `__post_init__` before - validation, [#560](https://github.com/samuelcolvin/pydantic/issues/560) by [@HeavenVolkoff](https://github.com/HeavenVolkoff) -* fix handling of generic types without specified parameters, [#550](https://github.com/samuelcolvin/pydantic/issues/550) by [@dmontagu](https://github.com/dmontagu) -* **breaking change** (maybe): this is the first release compiled with **cython**, see the docs and please - submit an issue if you run into problems - -## v0.27.0a1 (2019-05-26) - -* fix JSON Schema for `list`, `tuple`, and `set`, [#540](https://github.com/samuelcolvin/pydantic/issues/540) by [@tiangolo](https://github.com/tiangolo) -* compiling with cython, `manylinux` binaries, some other performance improvements, [#548](https://github.com/samuelcolvin/pydantic/issues/548) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.26 (2019-05-22) - -* fix to schema generation for `IPvAnyAddress`, `IPvAnyInterface`, `IPvAnyNetwork` [#498](https://github.com/samuelcolvin/pydantic/issues/498) by [@pilosus](https://github.com/pilosus) -* fix variable length tuples support, [#495](https://github.com/samuelcolvin/pydantic/issues/495) by [@pilosus](https://github.com/pilosus) -* fix return type hint for `create_model`, [#526](https://github.com/samuelcolvin/pydantic/issues/526) by [@dmontagu](https://github.com/dmontagu) -* **Breaking Change:** fix `.dict(skip_keys=True)` skipping values set via alias (this involves changing - `validate_model()` to always returns `Tuple[Dict[str, Any], Set[str], Optional[ValidationError]]`), [#517](https://github.com/samuelcolvin/pydantic/issues/517) by [@sommd](https://github.com/sommd) -* fix to schema generation for `IPv4Address`, `IPv6Address`, `IPv4Interface`, - `IPv6Interface`, `IPv4Network`, `IPv6Network` [#532](https://github.com/samuelcolvin/pydantic/issues/532) by [@euri10](https://github.com/euri10) -* add `Color` type, [#504](https://github.com/samuelcolvin/pydantic/issues/504) by [@pilosus](https://github.com/pilosus) and [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.25 (2019-05-05) - -* Improve documentation on self-referencing models and annotations, [#487](https://github.com/samuelcolvin/pydantic/issues/487) by [@theenglishway](https://github.com/theenglishway) -* fix `.dict()` with extra keys, [#490](https://github.com/samuelcolvin/pydantic/issues/490) by [@JaewonKim](https://github.com/JaewonKim) -* support `const` keyword in `Schema`, [#434](https://github.com/samuelcolvin/pydantic/issues/434) by [@Sean1708](https://github.com/Sean1708) - -## v0.24 (2019-04-23) - -* fix handling `ForwardRef` in sub-types, like `Union`, [#464](https://github.com/samuelcolvin/pydantic/issues/464) by [@tiangolo](https://github.com/tiangolo) -* fix secret serialization, [#465](https://github.com/samuelcolvin/pydantic/issues/465) by [@atheuz](https://github.com/atheuz) -* Support custom validators for dataclasses, [#454](https://github.com/samuelcolvin/pydantic/issues/454) by [@primal100](https://github.com/primal100) -* fix `parse_obj` to cope with dict-like objects, [#472](https://github.com/samuelcolvin/pydantic/issues/472) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix to schema generation in nested dataclass-based models, [#474](https://github.com/samuelcolvin/pydantic/issues/474) by [@NoAnyLove](https://github.com/NoAnyLove) -* fix `json` for `Path`, `FilePath`, and `DirectoryPath` objects, [#473](https://github.com/samuelcolvin/pydantic/issues/473) by [@mikegoodspeed](https://github.com/mikegoodspeed) - -## v0.23 (2019-04-04) - -* improve documentation for contributing section, [#441](https://github.com/samuelcolvin/pydantic/issues/441) by [@pilosus](https://github.com/pilosus) -* improve README.rst to include essential information about the package, [#446](https://github.com/samuelcolvin/pydantic/issues/446) by [@pilosus](https://github.com/pilosus) -* `IntEnum` support, [#444](https://github.com/samuelcolvin/pydantic/issues/444) by [@potykion](https://github.com/potykion) -* fix PyObject callable value, [#409](https://github.com/samuelcolvin/pydantic/issues/409) by [@pilosus](https://github.com/pilosus) -* fix `black` deprecation warnings after update, [#451](https://github.com/samuelcolvin/pydantic/issues/451) by [@pilosus](https://github.com/pilosus) -* fix `ForwardRef` collection bug, [#450](https://github.com/samuelcolvin/pydantic/issues/450) by [@tigerwings](https://github.com/tigerwings) -* Support specialized `ClassVars`, [#455](https://github.com/samuelcolvin/pydantic/issues/455) by [@tyrylu](https://github.com/tyrylu) -* fix JSON serialization for `ipaddress` types, [#333](https://github.com/samuelcolvin/pydantic/issues/333) by [@pilosus](https://github.com/pilosus) -* add `SecretStr` and `SecretBytes` types, [#452](https://github.com/samuelcolvin/pydantic/issues/452) by [@atheuz](https://github.com/atheuz) - -## v0.22 (2019-03-29) - -* add `IPv{4,6,Any}Network` and `IPv{4,6,Any}Interface` types from `ipaddress` stdlib, [#333](https://github.com/samuelcolvin/pydantic/issues/333) by [@pilosus](https://github.com/pilosus) -* add docs for `datetime` types, [#386](https://github.com/samuelcolvin/pydantic/issues/386) by [@pilosus](https://github.com/pilosus) -* fix to schema generation in dataclass-based models, [#408](https://github.com/samuelcolvin/pydantic/issues/408) by [@pilosus](https://github.com/pilosus) -* fix path in nested models, [#437](https://github.com/samuelcolvin/pydantic/issues/437) by [@kataev](https://github.com/kataev) -* add `Sequence` support, [#304](https://github.com/samuelcolvin/pydantic/issues/304) by [@pilosus](https://github.com/pilosus) - -## v0.21.0 (2019-03-15) - -* fix typo in `NoneIsNotAllowedError` message, [#414](https://github.com/samuelcolvin/pydantic/issues/414) by [@YaraslauZhylko](https://github.com/YaraslauZhylko) -* add `IPvAnyAddress`, `IPv4Address` and `IPv6Address` types, [#333](https://github.com/samuelcolvin/pydantic/issues/333) by [@pilosus](https://github.com/pilosus) - -## v0.20.1 (2019-02-26) - -* fix type hints of `parse_obj` and similar methods, [#405](https://github.com/samuelcolvin/pydantic/issues/405) by [@erosennin](https://github.com/erosennin) -* fix submodel validation, [#403](https://github.com/samuelcolvin/pydantic/issues/403) by [@samuelcolvin](https://github.com/samuelcolvin) -* correct type hints for `ValidationError.json`, [#406](https://github.com/samuelcolvin/pydantic/issues/406) by [@layday](https://github.com/layday) - -## v0.20.0 (2019-02-18) - -* fix tests for python 3.8, [#396](https://github.com/samuelcolvin/pydantic/issues/396) by [@samuelcolvin](https://github.com/samuelcolvin) -* Adds fields to the `dir` method for autocompletion in interactive sessions, [#398](https://github.com/samuelcolvin/pydantic/issues/398) by [@dgasmith](https://github.com/dgasmith) -* support `ForwardRef` (and therefore `from __future__ import annotations`) with dataclasses, [#397](https://github.com/samuelcolvin/pydantic/issues/397) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.20.0a1 (2019-02-13) - -* **breaking change** (maybe): more sophisticated argument parsing for validators, any subset of - `values`, `config` and `field` is now permitted, eg. `(cls, value, field)`, - however the variadic key word argument ("`**kwargs`") **must** be called `kwargs`, [#388](https://github.com/samuelcolvin/pydantic/issues/388) by [@samuelcolvin](https://github.com/samuelcolvin) -* **breaking change**: Adds `skip_defaults` argument to `BaseModel.dict()` to allow skipping of fields that - were not explicitly set, signature of `Model.construct()` changed, [#389](https://github.com/samuelcolvin/pydantic/issues/389) by [@dgasmith](https://github.com/dgasmith) -* add `py.typed` marker file for PEP-561 support, [#391](https://github.com/samuelcolvin/pydantic/issues/391) by [@je-l](https://github.com/je-l) -* Fix `extra` behaviour for multiple inheritance/mix-ins, [#394](https://github.com/samuelcolvin/pydantic/issues/394) by [@YaraslauZhylko](https://github.com/YaraslauZhylko) - -## v0.19.0 (2019-02-04) - -* Support `Callable` type hint, fix [#279](https://github.com/samuelcolvin/pydantic/issues/279) by [@proofit404](https://github.com/proofit404) -* Fix schema for fields with `validator` decorator, fix [#375](https://github.com/samuelcolvin/pydantic/issues/375) by [@tiangolo](https://github.com/tiangolo) -* Add `multiple_of` constraint to `ConstrainedDecimal`, `ConstrainedFloat`, `ConstrainedInt` - and their related types `condecimal`, `confloat`, and `conint` [#371](https://github.com/samuelcolvin/pydantic/issues/371), thanks [@StephenBrown2](https://github.com/StephenBrown2) -* Deprecated `ignore_extra` and `allow_extra` Config fields in favor of `extra`, [#352](https://github.com/samuelcolvin/pydantic/issues/352) by [@liiight](https://github.com/liiight) -* Add type annotations to all functions, test fully with mypy, [#373](https://github.com/samuelcolvin/pydantic/issues/373) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix for 'missing' error with `validate_all` or `validate_always`, [#381](https://github.com/samuelcolvin/pydantic/issues/381) by [@samuelcolvin](https://github.com/samuelcolvin) -* Change the second/millisecond watershed for date/datetime parsing to `2e10`, [#385](https://github.com/samuelcolvin/pydantic/issues/385) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.18.2 (2019-01-22) - -* Fix to schema generation with `Optional` fields, fix [#361](https://github.com/samuelcolvin/pydantic/issues/361) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.18.1 (2019-01-17) - -* add `ConstrainedBytes` and `conbytes` types, [#315](https://github.com/samuelcolvin/pydantic/issues/315) [@Gr1N](https://github.com/Gr1N) -* adding `MANIFEST.in` to include license in package `.tar.gz`, [#358](https://github.com/samuelcolvin/pydantic/issues/358) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.18.0 (2019-01-13) - -* **breaking change**: don't call validators on keys of dictionaries, [#254](https://github.com/samuelcolvin/pydantic/issues/254) by [@samuelcolvin](https://github.com/samuelcolvin) -* Fix validators with `always=True` when the default is `None` or the type is optional, also prevent - `whole` validators being called for sub-fields, fix [#132](https://github.com/samuelcolvin/pydantic/issues/132) by [@samuelcolvin](https://github.com/samuelcolvin) -* improve documentation for settings priority and allow it to be easily changed, [#343](https://github.com/samuelcolvin/pydantic/issues/343) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix `ignore_extra=False` and `allow_population_by_alias=True`, fix [#257](https://github.com/samuelcolvin/pydantic/issues/257) by [@samuelcolvin](https://github.com/samuelcolvin) -* **breaking change**: Set `BaseConfig` attributes `min_anystr_length` and `max_anystr_length` to - `None` by default, fix [#349](https://github.com/samuelcolvin/pydantic/issues/349) in [#350](https://github.com/samuelcolvin/pydantic/issues/350) by [@tiangolo](https://github.com/tiangolo) -* add support for postponed annotations, [#348](https://github.com/samuelcolvin/pydantic/issues/348) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.17.0 (2018-12-27) - -* fix schema for `timedelta` as number, [#325](https://github.com/samuelcolvin/pydantic/issues/325) by [@tiangolo](https://github.com/tiangolo) -* prevent validators being called repeatedly after inheritance, [#327](https://github.com/samuelcolvin/pydantic/issues/327) by [@samuelcolvin](https://github.com/samuelcolvin) -* prevent duplicate validator check in ipython, fix [#312](https://github.com/samuelcolvin/pydantic/issues/312) by [@samuelcolvin](https://github.com/samuelcolvin) -* add "Using Pydantic" section to docs, [#323](https://github.com/samuelcolvin/pydantic/issues/323) by [@tiangolo](https://github.com/tiangolo) & [#326](https://github.com/samuelcolvin/pydantic/issues/326) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix schema generation for fields annotated as `: dict`, `: list`, - `: tuple` and `: set`, [#330](https://github.com/samuelcolvin/pydantic/issues/330) & [#335](https://github.com/samuelcolvin/pydantic/issues/335) by [@nkonin](https://github.com/nkonin) -* add support for constrained strings as dict keys in schema, [#332](https://github.com/samuelcolvin/pydantic/issues/332) by [@tiangolo](https://github.com/tiangolo) -* support for passing Config class in dataclasses decorator, [#276](https://github.com/samuelcolvin/pydantic/issues/276) by [@jarekkar](https://github.com/jarekkar) - (**breaking change**: this supersedes the `validate_assignment` argument with `config`) -* support for nested dataclasses, [#334](https://github.com/samuelcolvin/pydantic/issues/334) by [@samuelcolvin](https://github.com/samuelcolvin) -* better errors when getting an `ImportError` with `PyObject`, [#309](https://github.com/samuelcolvin/pydantic/issues/309) by [@samuelcolvin](https://github.com/samuelcolvin) -* rename `get_validators` to `__get_validators__`, deprecation warning on use of old name, [#338](https://github.com/samuelcolvin/pydantic/issues/338) by [@samuelcolvin](https://github.com/samuelcolvin) -* support `ClassVar` by excluding such attributes from fields, [#184](https://github.com/samuelcolvin/pydantic/issues/184) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.16.1 (2018-12-10) - -* fix `create_model` to correctly use the passed `__config__`, [#320](https://github.com/samuelcolvin/pydantic/issues/320) by [@hugoduncan](https://github.com/hugoduncan) - -## v0.16.0 (2018-12-03) - -* **breaking change**: refactor schema generation to be compatible with JSON Schema and OpenAPI specs, [#308](https://github.com/samuelcolvin/pydantic/issues/308) by [@tiangolo](https://github.com/tiangolo) -* add `schema` to `schema` module to generate top-level schemas from base models, [#308](https://github.com/samuelcolvin/pydantic/issues/308) by [@tiangolo](https://github.com/tiangolo) -* add additional fields to `Schema` class to declare validation for `str` and numeric values, [#311](https://github.com/samuelcolvin/pydantic/issues/311) by [@tiangolo](https://github.com/tiangolo) -* rename `_schema` to `schema` on fields, [#318](https://github.com/samuelcolvin/pydantic/issues/318) by [@samuelcolvin](https://github.com/samuelcolvin) -* add `case_insensitive` option to `BaseSettings` `Config`, [#277](https://github.com/samuelcolvin/pydantic/issues/277) by [@jasonkuhrt](https://github.com/jasonkuhrt) - -## v0.15.0 (2018-11-18) - -* move codebase to use black, [#287](https://github.com/samuelcolvin/pydantic/issues/287) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix alias use in settings, [#286](https://github.com/samuelcolvin/pydantic/issues/286) by [@jasonkuhrt](https://github.com/jasonkuhrt) and [@samuelcolvin](https://github.com/samuelcolvin) -* fix datetime parsing in `parse_date`, [#298](https://github.com/samuelcolvin/pydantic/issues/298) by [@samuelcolvin](https://github.com/samuelcolvin) -* allow dataclass inheritance, fix [#293](https://github.com/samuelcolvin/pydantic/issues/293) by [@samuelcolvin](https://github.com/samuelcolvin) -* fix `PyObject = None`, fix [#305](https://github.com/samuelcolvin/pydantic/issues/305) by [@samuelcolvin](https://github.com/samuelcolvin) -* allow `Pattern` type, fix [#303](https://github.com/samuelcolvin/pydantic/issues/303) by [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.14.0 (2018-10-02) - -* dataclasses decorator, [#269](https://github.com/samuelcolvin/pydantic/issues/269) by [@Gaunt](https://github.com/Gaunt) and [@samuelcolvin](https://github.com/samuelcolvin) - -## v0.13.1 (2018-09-21) - -* fix issue where int_validator doesn't cast a `bool` to an `int` [#264](https://github.com/samuelcolvin/pydantic/issues/264) by [@nphyatt](https://github.com/nphyatt) -* add deep copy support for `BaseModel.copy()` [#249](https://github.com/samuelcolvin/pydantic/issues/249), [@gangefors](https://github.com/gangefors) - -## v0.13.0 (2018-08-25) - -* raise an exception if a field's name shadows an existing `BaseModel` attribute [#242](https://github.com/samuelcolvin/pydantic/issues/242) -* add `UrlStr` and `urlstr` types [#236](https://github.com/samuelcolvin/pydantic/issues/236) -* timedelta json encoding ISO8601 and total seconds, custom json encoders [#247](https://github.com/samuelcolvin/pydantic/issues/247), by [@cfkanesan](https://github.com/cfkanesan) and [@samuelcolvin](https://github.com/samuelcolvin) -* allow `timedelta` objects as values for properties of type `timedelta` (matches `datetime` etc. behavior) [#247](https://github.com/samuelcolvin/pydantic/issues/247) - -## v0.12.1 (2018-07-31) - -* fix schema generation for fields defined using `typing.Any` [#237](https://github.com/samuelcolvin/pydantic/issues/237) - -## v0.12.0 (2018-07-31) - -* add `by_alias` argument in `.dict()` and `.json()` model methods [#205](https://github.com/samuelcolvin/pydantic/issues/205) -* add Json type support [#214](https://github.com/samuelcolvin/pydantic/issues/214) -* support tuples [#227](https://github.com/samuelcolvin/pydantic/issues/227) -* major improvements and changes to schema [#213](https://github.com/samuelcolvin/pydantic/issues/213) - -## v0.11.2 (2018-07-05) - -* add `NewType` support [#115](https://github.com/samuelcolvin/pydantic/issues/115) -* fix `list`, `set` & `tuple` validation [#225](https://github.com/samuelcolvin/pydantic/issues/225) -* separate out `validate_model` method, allow errors to be returned along with valid values [#221](https://github.com/samuelcolvin/pydantic/issues/221) - -## v0.11.1 (2018-07-02) - -* support Python 3.7 [#216](https://github.com/samuelcolvin/pydantic/issues/216), thanks [@layday](https://github.com/layday) -* Allow arbitrary types in model [#209](https://github.com/samuelcolvin/pydantic/issues/209), thanks [@oldPadavan](https://github.com/oldPadavan) - -## v0.11.0 (2018-06-28) - -* make `list`, `tuple` and `set` types stricter [#86](https://github.com/samuelcolvin/pydantic/issues/86) -* **breaking change**: remove msgpack parsing [#201](https://github.com/samuelcolvin/pydantic/issues/201) -* add `FilePath` and `DirectoryPath` types [#10](https://github.com/samuelcolvin/pydantic/issues/10) -* model schema generation [#190](https://github.com/samuelcolvin/pydantic/issues/190) -* JSON serialisation of models and schemas [#133](https://github.com/samuelcolvin/pydantic/issues/133) - -## v0.10.0 (2018-06-11) - -* add `Config.allow_population_by_alias` [#160](https://github.com/samuelcolvin/pydantic/issues/160), thanks [@bendemaree](https://github.com/bendemaree) -* **breaking change**: new errors format [#179](https://github.com/samuelcolvin/pydantic/issues/179), thanks [@Gr1N](https://github.com/Gr1N) -* **breaking change**: removed `Config.min_number_size` and `Config.max_number_size` [#183](https://github.com/samuelcolvin/pydantic/issues/183), thanks [@Gr1N](https://github.com/Gr1N) -* **breaking change**: correct behaviour of `lt` and `gt` arguments to `conint` etc. [#188](https://github.com/samuelcolvin/pydantic/issues/188) - for the old behaviour use `le` and `ge` [#194](https://github.com/samuelcolvin/pydantic/issues/194), thanks [@jaheba](https://github.com/jaheba) -* added error context and ability to redefine error message templates using `Config.error_msg_templates` [#183](https://github.com/samuelcolvin/pydantic/issues/183), - thanks [@Gr1N](https://github.com/Gr1N) -* fix typo in validator exception [#150](https://github.com/samuelcolvin/pydantic/issues/150) -* copy defaults to model values, so different models don't share objects [#154](https://github.com/samuelcolvin/pydantic/issues/154) - -## v0.9.1 (2018-05-10) - -* allow custom `get_field_config` on config classes [#159](https://github.com/samuelcolvin/pydantic/issues/159) -* add `UUID1`, `UUID3`, `UUID4` and `UUID5` types [#167](https://github.com/samuelcolvin/pydantic/issues/167), thanks [@Gr1N](https://github.com/Gr1N) -* modify some inconsistent docstrings and annotations [#173](https://github.com/samuelcolvin/pydantic/issues/173), thanks [@YannLuo](https://github.com/YannLuo) -* fix type annotations for exotic types [#171](https://github.com/samuelcolvin/pydantic/issues/171), thanks [@Gr1N](https://github.com/Gr1N) -* re-use type validators in exotic types [#171](https://github.com/samuelcolvin/pydantic/issues/171) -* scheduled monthly requirements updates [#168](https://github.com/samuelcolvin/pydantic/issues/168) -* add `Decimal`, `ConstrainedDecimal` and `condecimal` types [#170](https://github.com/samuelcolvin/pydantic/issues/170), thanks [@Gr1N](https://github.com/Gr1N) - -## v0.9.0 (2018-04-28) - -* tweak email-validator import error message [#145](https://github.com/samuelcolvin/pydantic/issues/145) -* fix parse error of `parse_date()` and `parse_datetime()` when input is 0 [#144](https://github.com/samuelcolvin/pydantic/issues/144), thanks [@YannLuo](https://github.com/YannLuo) -* add `Config.anystr_strip_whitespace` and `strip_whitespace` kwarg to `constr`, - by default values is `False` [#163](https://github.com/samuelcolvin/pydantic/issues/163), thanks [@Gr1N](https://github.com/Gr1N) -* add `ConstrainedFloat`, `confloat`, `PositiveFloat` and `NegativeFloat` types [#166](https://github.com/samuelcolvin/pydantic/issues/166), thanks [@Gr1N](https://github.com/Gr1N) - -## v0.8.0 (2018-03-25) - -* fix type annotation for `inherit_config` [#139](https://github.com/samuelcolvin/pydantic/issues/139) -* **breaking change**: check for invalid field names in validators [#140](https://github.com/samuelcolvin/pydantic/issues/140) -* validate attributes of parent models [#141](https://github.com/samuelcolvin/pydantic/issues/141) -* **breaking change**: email validation now uses - [email-validator](https://github.com/JoshData/python-email-validator) [#142](https://github.com/samuelcolvin/pydantic/issues/142) - -## v0.7.1 (2018-02-07) - -* fix bug with `create_model` modifying the base class - -## v0.7.0 (2018-02-06) - -* added compatibility with abstract base classes (ABCs) [#123](https://github.com/samuelcolvin/pydantic/issues/123) -* add `create_model` method [#113](https://github.com/samuelcolvin/pydantic/issues/113) [#125](https://github.com/samuelcolvin/pydantic/issues/125) -* **breaking change**: rename `.config` to `.__config__` on a model -* **breaking change**: remove deprecated `.values()` on a model, use `.dict()` instead -* remove use of `OrderedDict` and use simple dict [#126](https://github.com/samuelcolvin/pydantic/issues/126) -* add `Config.use_enum_values` [#127](https://github.com/samuelcolvin/pydantic/issues/127) -* add wildcard validators of the form `@validate('*')` [#128](https://github.com/samuelcolvin/pydantic/issues/128) - -## v0.6.4 (2018-02-01) - -* allow python date and times objects [#122](https://github.com/samuelcolvin/pydantic/issues/122) - -## v0.6.3 (2017-11-26) - -* fix direct install without `README.rst` present - -## v0.6.2 (2017-11-13) - -* errors for invalid validator use -* safer check for complex models in `Settings` - -## v0.6.1 (2017-11-08) - -* prevent duplicate validators, [#101](https://github.com/samuelcolvin/pydantic/issues/101) -* add `always` kwarg to validators, [#102](https://github.com/samuelcolvin/pydantic/issues/102) - -## v0.6.0 (2017-11-07) - -* assignment validation [#94](https://github.com/samuelcolvin/pydantic/issues/94), thanks petroswork! -* JSON in environment variables for complex types, [#96](https://github.com/samuelcolvin/pydantic/issues/96) -* add `validator` decorators for complex validation, [#97](https://github.com/samuelcolvin/pydantic/issues/97) -* depreciate `values(...)` and replace with `.dict(...)`, [#99](https://github.com/samuelcolvin/pydantic/issues/99) - -## v0.5.0 (2017-10-23) - -* add `UUID` validation [#89](https://github.com/samuelcolvin/pydantic/issues/89) -* remove `index` and `track` from error object (json) if they're null [#90](https://github.com/samuelcolvin/pydantic/issues/90) -* improve the error text when a list is provided rather than a dict [#90](https://github.com/samuelcolvin/pydantic/issues/90) -* add benchmarks table to docs [#91](https://github.com/samuelcolvin/pydantic/issues/91) - -## v0.4.0 (2017-07-08) - -* show length in string validation error -* fix aliases in config during inheritance [#55](https://github.com/samuelcolvin/pydantic/issues/55) -* simplify error display -* use unicode ellipsis in `truncate` -* add `parse_obj`, `parse_raw` and `parse_file` helper functions [#58](https://github.com/samuelcolvin/pydantic/issues/58) -* switch annotation only fields to come first in fields list not last - -## v0.3.0 (2017-06-21) - -* immutable models via `config.allow_mutation = False`, associated cleanup and performance improvement [#44](https://github.com/samuelcolvin/pydantic/issues/44) -* immutable helper methods `construct()` and `copy()` [#53](https://github.com/samuelcolvin/pydantic/issues/53) -* allow pickling of models [#53](https://github.com/samuelcolvin/pydantic/issues/53) -* `setattr` is removed as `__setattr__` is now intelligent [#44](https://github.com/samuelcolvin/pydantic/issues/44) -* `raise_exception` removed, Models now always raise exceptions [#44](https://github.com/samuelcolvin/pydantic/issues/44) -* instance method validators removed -* django-restful-framework benchmarks added [#47](https://github.com/samuelcolvin/pydantic/issues/47) -* fix inheritance bug [#49](https://github.com/samuelcolvin/pydantic/issues/49) -* make str type stricter so list, dict etc are not coerced to strings. [#52](https://github.com/samuelcolvin/pydantic/issues/52) -* add `StrictStr` which only always strings as input [#52](https://github.com/samuelcolvin/pydantic/issues/52) - -## v0.2.1 (2017-06-07) - -* pypi and travis together messed up the deploy of `v0.2` this should fix it - -## v0.2.0 (2017-06-07) - -* **breaking change**: `values()` on a model is now a method not a property, - takes `include` and `exclude` arguments -* allow annotation only fields to support mypy -* add pretty `to_string(pretty=True)` method for models - -## v0.1.0 (2017-06-03) - -* add docs -* add history - - diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/RECORD b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/RECORD deleted file mode 100644 index f53a8b47..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/RECORD +++ /dev/null @@ -1,75 +0,0 @@ -pydantic-1.7.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pydantic-1.7.2.dist-info/LICENSE,sha256=Zrrb_lZhjsUt3L_aYkUOQ3UtFv4efK5400bH7RCjUwY,1115 -pydantic-1.7.2.dist-info/METADATA,sha256=t6h1QjUf5pcNnow45-iJ-ogWu4TcspzXF5Uvxsmpj-M,83216 -pydantic-1.7.2.dist-info/RECORD,, -pydantic-1.7.2.dist-info/WHEEL,sha256=kyTh19hYapxFQnJ2J_oso2bAphHNwCojNuQrMpP_-Ug,111 -pydantic-1.7.2.dist-info/top_level.txt,sha256=cmo_5n0F_YY5td5nPZBfdjBENkmGg_pE5ShWXYbXxTM,9 -pydantic/__init__.cpython-38-x86_64-linux-gnu.so,sha256=4ws6Bf65QFhrGGgR-TFDXYq92lXhtJAtxuF3yGH2TLI,197976 -pydantic/__init__.py,sha256=WD_wSV_5-W1HKB1EGIHAE-bCIZh96pIROt5URN58O2M,2103 -pydantic/__pycache__/__init__.cpython-38.pyc,, -pydantic/__pycache__/class_validators.cpython-38.pyc,, -pydantic/__pycache__/color.cpython-38.pyc,, -pydantic/__pycache__/dataclasses.cpython-38.pyc,, -pydantic/__pycache__/datetime_parse.cpython-38.pyc,, -pydantic/__pycache__/decorator.cpython-38.pyc,, -pydantic/__pycache__/env_settings.cpython-38.pyc,, -pydantic/__pycache__/error_wrappers.cpython-38.pyc,, -pydantic/__pycache__/errors.cpython-38.pyc,, -pydantic/__pycache__/fields.cpython-38.pyc,, -pydantic/__pycache__/generics.cpython-38.pyc,, -pydantic/__pycache__/json.cpython-38.pyc,, -pydantic/__pycache__/main.cpython-38.pyc,, -pydantic/__pycache__/mypy.cpython-38.pyc,, -pydantic/__pycache__/networks.cpython-38.pyc,, -pydantic/__pycache__/parse.cpython-38.pyc,, -pydantic/__pycache__/schema.cpython-38.pyc,, -pydantic/__pycache__/tools.cpython-38.pyc,, -pydantic/__pycache__/types.cpython-38.pyc,, -pydantic/__pycache__/typing.cpython-38.pyc,, -pydantic/__pycache__/utils.cpython-38.pyc,, -pydantic/__pycache__/validators.cpython-38.pyc,, -pydantic/__pycache__/version.cpython-38.pyc,, -pydantic/class_validators.cpython-38-x86_64-linux-gnu.so,sha256=p5kwHQcK1KPlyCR5LH8SIEU3eQwzuE4cVgV9DyWchqg,2780192 -pydantic/class_validators.py,sha256=T5j3YIpBSQzg--A9i0qJJB9CXxbaG5DQ9sSz_Ib9PKY,13410 -pydantic/color.cpython-38-x86_64-linux-gnu.so,sha256=uxfgzwpNC2N3m_tcNfrAUkSfFjcuvzTzpQxoCffxfnE,3552424 -pydantic/color.py,sha256=zPItEwj2aH9zv7N1hzR3gcPA2VbMLBGAwz1X8BT1Ddg,16635 -pydantic/dataclasses.cpython-38-x86_64-linux-gnu.so,sha256=Pzkw6yC2fXz2U4ry42935N1LtGwE64OKcpNkykCJKiQ,1665312 -pydantic/dataclasses.py,sha256=GOVgZU-plP4e68F5HnzKXLuKWCA1j0PW0O0VZCN40e0,7694 -pydantic/datetime_parse.cpython-38-x86_64-linux-gnu.so,sha256=hGx5w0bhFNlLOEbKLXi9J-yPqvhZdY7uJhiYVGfhn6M,1453088 -pydantic/datetime_parse.py,sha256=zAaRufbpKmKF1yLgAgTEhCh5jR9v791DlurnmdgjNc0,7503 -pydantic/decorator.cpython-38-x86_64-linux-gnu.so,sha256=yxdU5L0Owr2wsbp8t4-0r-pJDufSSmaAXLaRvrUhvWU,2123272 -pydantic/decorator.py,sha256=WuDzUYVRTiNXVaqNVT1eeb17ZTIdk9dsp0xOhiD-AyM,8819 -pydantic/env_settings.cpython-38-x86_64-linux-gnu.so,sha256=GSyzHx33s_zpKnYKjhsLivRsYHp5EyWdivRlil8dVKs,1613232 -pydantic/env_settings.py,sha256=2GGvb3hAPdLQoK0CcUX7O7774F-AF_NS2jAfRB-ehFE,6718 -pydantic/error_wrappers.cpython-38-x86_64-linux-gnu.so,sha256=m8i02I7g2UQuMRMsdF-ArE4ZzCtb8zHH-b2zVcV6UYM,1528480 -pydantic/error_wrappers.py,sha256=gpOmSe8ICyJqzoycDPHp98vslUFyCocjA-HPolLoC3k,4969 -pydantic/errors.cpython-38-x86_64-linux-gnu.so,sha256=bJ6TpQT1IYpQuTycbo2vCku_cJfuuUcm0LBdutgPhA0,6663104 -pydantic/errors.py,sha256=p4Isvi6dDx9mEhG2U8Hb6LHfD2QqINlimkTD0iHpWvw,15513 -pydantic/fields.cpython-38-x86_64-linux-gnu.so,sha256=kISMeUyeRtieWjl-EXoqzEjQ-EVT70k895Cc85Q1paY,6646488 -pydantic/fields.py,sha256=ngr7257HoDQZ1HHDR5UUi-Xbv0L3fC3hdV5F5jgT3jY,31497 -pydantic/generics.py,sha256=91R-2A2exMrEjNr9JSARBY45Z1SbZNTeJtt1G8V7qyI,6892 -pydantic/json.cpython-38-x86_64-linux-gnu.so,sha256=ZphZ3-ZfVnGrGJM2L-_wa0E4u6ZpAsRQMLbwXpv6Als,967544 -pydantic/json.py,sha256=5ZmiWnJbqPzBpmPwberF58X1pxnrep9MQMgPxlaLytA,2564 -pydantic/main.cpython-38-x86_64-linux-gnu.so,sha256=qmNNmLNNzgm6R5NJoH8llCOy6AZ3p0GBPfPRKOxTojM,8892160 -pydantic/main.py,sha256=5NPl-B7-MvFvg-Zbgo5mti3atrflEsUHEbldX-_KTbg,38979 -pydantic/mypy.cpython-38-x86_64-linux-gnu.so,sha256=IwipWUzKSlDscqInZmU5dyY6vaXVEazxDyThLpwZnVQ,6467120 -pydantic/mypy.py,sha256=nVfF7U1hdY4heM1iiuBOid8rX-fNEdg4lG4qaAvENf4,27651 -pydantic/networks.cpython-38-x86_64-linux-gnu.so,sha256=xbhBCUM7Kk2iWf10rZjamtmjHgIyBMmptAhHjCFanIQ,4111640 -pydantic/networks.py,sha256=dWO5rfJpO82FI3D65Fdh7Bib7rDRgUhYXzAU59Gs7S0,14206 -pydantic/parse.cpython-38-x86_64-linux-gnu.so,sha256=nwZ9oAAwRBy2UwddgZoGtwzB4LJVL5TrnWX3qceA0IQ,527240 -pydantic/parse.py,sha256=rrVhaWLK8t03rT3oxvC6uRLuTF5iZ2NKGvGqs4iQEM0,1810 -pydantic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pydantic/schema.cpython-38-x86_64-linux-gnu.so,sha256=A934v0Mgk6nJPE6-MB7iJRlS3Kyd_JW3WkhcFuP3L9E,8271984 -pydantic/schema.py,sha256=397iPWFL6FJDXypQrkpcs1MOuHO8BorRrrkObhYjtW0,39576 -pydantic/tools.cpython-38-x86_64-linux-gnu.so,sha256=Fj2JRxjed54RP26ns_kYN_Hqid_hiGcNOM7EOxvZ9Gw,699680 -pydantic/tools.py,sha256=rmm4k7htaA8PkeFdytxTo-Mb-ARrrS0WUGNRPHnqi6Y,2169 -pydantic/types.cpython-38-x86_64-linux-gnu.so,sha256=QHx3M_z8MGle73SnN9dZJSVeOO2EZE7SlC5XoYGWzEI,10851136 -pydantic/types.py,sha256=AtF5BEMpfdZ4R8n-bWd4bOMlmzA-Qm4u3Ll3ZybGIxg,25544 -pydantic/typing.cpython-38-x86_64-linux-gnu.so,sha256=Rciq-fgu7QoJvuidZ2Le1MNARiWuJ4xgJG1pBy5L-vg,2007848 -pydantic/typing.py,sha256=5_D1dqHBTfaywfuTcy3PzpSFjghc3rczwlant2j7kSY,9444 -pydantic/utils.cpython-38-x86_64-linux-gnu.so,sha256=tAYlj5QzurpaQtUGPi3sXOH5d4XPRyYyb1N07VYGFLY,5439856 -pydantic/utils.py,sha256=97tMu1bntZtuGPAWQifphYEqEizjlxaUJ38fvCqcKDU,20860 -pydantic/validators.cpython-38-x86_64-linux-gnu.so,sha256=E3xBMqK5_xNPO1ArSuw86tLeoDVI0-Y-VOzG_L7U52E,5339632 -pydantic/validators.py,sha256=LXfDOgvSnjdwt5-aPvgHe20BDAlGmMS7YyTFVSvJizw,16839 -pydantic/version.cpython-38-x86_64-linux-gnu.so,sha256=YPcoqoVJSw-t2I0zSWaI0WZgIG7be2e622QZPsqf6EM,562416 -pydantic/version.py,sha256=ZpcDbz7z_32Lf1bG98s2LkZ5f8Pp3va0PJc4TIZ1URE,838 diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/WHEEL b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/WHEEL deleted file mode 100644 index d965d81a..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: false -Tag: cp38-cp38-manylinux2014_x86_64 - diff --git a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/top_level.txt b/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/top_level.txt deleted file mode 100644 index 572b352f..00000000 --- a/env/lib/python3.8/site-packages/pydantic-1.7.2.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pydantic diff --git a/env/lib/python3.8/site-packages/pydantic/__init__.py b/env/lib/python3.8/site-packages/pydantic/__init__.py deleted file mode 100644 index 5cfc0583..00000000 --- a/env/lib/python3.8/site-packages/pydantic/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -# flake8: noqa -from . import dataclasses -from .class_validators import root_validator, validator -from .decorator import validate_arguments -from .env_settings import BaseSettings -from .error_wrappers import ValidationError -from .errors import * -from .fields import Field, PrivateAttr, Required, Schema -from .main import * -from .networks import * -from .parse import Protocol -from .tools import * -from .types import * -from .version import VERSION - -# WARNING __all__ from .errors is not included here, it will be removed as an export here in v2 -# please use "from pydantic.errors import ..." instead -__all__ = [ - # dataclasses - 'dataclasses', - # class_validators - 'root_validator', - 'validator', - # decorator - 'validate_arguments', - # env_settings - 'BaseSettings', - # error_wrappers - 'ValidationError', - # fields - 'Field', - 'Required', - 'Schema', - # main - 'BaseConfig', - 'BaseModel', - 'Extra', - 'compiled', - 'create_model', - 'validate_model', - # network - 'AnyUrl', - 'AnyHttpUrl', - 'HttpUrl', - 'stricturl', - 'EmailStr', - 'NameEmail', - 'IPvAnyAddress', - 'IPvAnyInterface', - 'IPvAnyNetwork', - 'PostgresDsn', - 'RedisDsn', - 'validate_email', - # parse - 'Protocol', - # tools - 'parse_file_as', - 'parse_obj_as', - 'parse_raw_as', - # types - 'NoneStr', - 'NoneBytes', - 'StrBytes', - 'NoneStrBytes', - 'StrictStr', - 'ConstrainedBytes', - 'conbytes', - 'ConstrainedList', - 'conlist', - 'ConstrainedSet', - 'conset', - 'ConstrainedStr', - 'constr', - 'PyObject', - 'ConstrainedInt', - 'conint', - 'PositiveInt', - 'NegativeInt', - 'ConstrainedFloat', - 'confloat', - 'PositiveFloat', - 'NegativeFloat', - 'ConstrainedDecimal', - 'condecimal', - 'UUID1', - 'UUID3', - 'UUID4', - 'UUID5', - 'FilePath', - 'DirectoryPath', - 'Json', - 'JsonWrapper', - 'SecretStr', - 'SecretBytes', - 'StrictBool', - 'StrictInt', - 'StrictFloat', - 'PaymentCardNumber', - 'PrivateAttr', - 'ByteSize', - # version - 'VERSION', -] diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 6969b521c54b6a72569759651d6fc00eb15e6685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1765 zcma)6>2ecC5Z1~%R?_OQF<{6EIYnY@4u>2B@EMzctXMIrnm=3P?Xf&Cdt_!LM?65@ zC8<0`9%KLJS6(5%(laAtQAMhbaaq*jI;mS+5se>BZdC+v zlQiQNX~k{Qjyt3?_0L;>MJ!nDiwp50S)BSVPJNfGu8GU>5?MlD9U2fo6I#%Q4$Q*> zT!2Nm2$$e8EWs7H3U9&N@D98S@4@?U4X(on@F9EzAHyf`DRkimdQ<>LZL5y9P5*AW99K|fr3a!Bg zRcyet=E>0T_A{5w(_~x9RHDhd(JkfW9nJ*gjlSe#s@b~MGWQSI&m%4wj07|McR(;C7Q`&8nH8fkLlA?z95Z$s`L;;w^Tx~DZni{F9}=2 zg>0JBH8Uy|3y<*#Ayp)BG(CDg!z4X5tlCQx<|;$5G0{vBAGt%p)azIc?RX*+-ND`| zY!y!!Op~HCIkM^P8Q&AGG^wIX7|@#W;5d*9Iuz>H?D%wRNA33~`$x}N^m+ug$VPC~ zrYl_YF*C+Sj}7S=nXPa~q*R-?njBlyJj-&9=2@Pj3o})2v53bM-!SIF6qgSV_qJ{k ztL`{;*Qqt)?_kgSRG*OM77lHM3o@~^^jM_{X&CvFq*=yr76uHb%eJ%OpzCDawRs~= z1;*Hx+tWGdYMk%WiP^4ADxo)ukC>F^TS$EKhyj1eWD9Apdo?fE#ULHKz~^hL&Q~R` z;mJ~Imf3C%30N`?@x9n}wL3&w_y?&BPhIKC?o?i}MwM5N&DturW2TJrMaxS#l{l}7 zn_`uh?JT-6Eo(d?n)D=NDzA>2RQN@(mFLwkq(X$@Zw0wzo@m5BYb!d=Rx+L~kCKc= zFBmMJo-ihsSC1geZY!~pO@JnvM=N2-6RyMXW;V(F`?#(n!5)}Tg!&yt;B~yf-oCfw m`FICTR*J=qK*B({BO$nKel4=kADGsZ1(X0 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/class_validators.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/class_validators.cpython-38.pyc deleted file mode 100644 index 229837ec34be405b11f847615f0e06df3b586716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12934 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 z 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
    _@vx0mnSUH?_eQWKfuj2ytr41tu3gw2X}>!b zSv*%8#Nl2qsFJRGdY+=$VtB^`y5LQq4o$o*D4>TnCKoaw->jgXOGF`jH+sKL(_N(E zORyiW@fWZ}*iRGo2N1al`3A0$bbYi?Por)lh9B04jA292l{0rVOcjf)S}GPp18Iix zUf9c-Anc)P^a^JwHT z>2e?_DG}t?)CRk>ru3&?I?{L=W%V+jqbq+viIz2#*2ncxqYrlv*8l(j diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/decorator.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/decorator.cpython-38.pyc deleted file mode 100644 index 996a5ca0bd9aff17afae7cba6debb5c8f636d8a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7552 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 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/env_settings.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/env_settings.cpython-38.pyc deleted file mode 100644 index d8b2382a3c28c491eebf78e06170e22a3ce7323f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5884 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 UR6GK_%;9%Vca4VG_zj!;FTMxPR{#J2 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/error_wrappers.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/error_wrappers.cpython-38.pyc deleted file mode 100644 index 6a31f60006393b3b8e92412fccc2010d9a3ee538..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5483 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 Ibry^N10b@9-~a#s diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/errors.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/errors.cpython-38.pyc deleted file mode 100644 index af3257d2706d5011dfbd1115f2c7f62a53735d24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22533 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 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/generics.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/generics.cpython-38.pyc deleted file mode 100644 index 545289ba7a7e9af773d43e789f6f09e47b0229d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6485 zcmaJ_TXP&o74Dvyot?c&D_N3l`8JLd!-6dvlaP?85+}}uK%xX}$H|0b8EwzXBh6mi zGiyg%vndK0Y^s1V@W2C3mHg;e9(m*^@HnsVK&to!hD!KO_ugcM>{ie8_4Mh}=klGo zTB#Hne*Itlt^V(2#{NN#>7RqfMU?n2oUyA+Fu^0{(c6f4%kYer>6tCdvsyVX*Rnmk zmG|;3$8%Z*uh1%b#a78HwaQ+(Rq-mE2~$|nOl#JgRrOp{ZOwUet$A-=we9FYYr$J+ zEqaTpoyQ(a-jb?2(ZSXs?+|Ap^9~2OzzGV0d6)&Iz(m~?g{E7fbj9p_Q&h#=ZOc23o@3}A?;^OE z$LImEfYB3J=?3#^CDjyH!`9I~EqBcG+=x%Hc;6CB;vndp)N?^?dX=Ik4q>;$Vi~iZ z0GFr4k^6=?DvqK3BxvRX7u=m9n&S9^V&b649K&a8$XC)vzKkkk{5)USu_B>o(l!fHHQ-0+j@fvo#cRKMv*q41NAjB7?# zcs&dv@n*Z($%=1xL=dSq4ZPyVf$GW14H@`JP;b#Vh!ts%jtn=#Hd^yh&<=xkQV-*} zx89&btYi!I4b8pcC9XI8#`Pep43DJ9UdhVSO;F0McY1BnAR$fvY&0&S#DBmeU>+CD zGob$5Glk(=c^cw=5qwi^akkA8Eg6i`f*_+PlZgzfT_rMzi8-~%Hy1luae<kC5KbH z$-+_-oDJ|aP@?*gU<Xz3<`?|Urn49`(%E}F z{%ewllOpL&�nzR-L>`XWV__0iCOwRL26u7w+wLe&(VmOBe%H9 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 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/main.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/main.cpython-38.pyc deleted file mode 100644 index ef11802c839d4f9e551518955fd4599d5fb3923f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27437 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

    5xEjXuMPj#jW-Wc%Iz?K@DekY+@)oG-( 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 VF7@O$at|lt22C5HaVUKE{{o@00i*x` diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/mypy.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/mypy.cpython-38.pyc deleted file mode 100644 index b541ec6d0f2a591d7b92e9eafacebfe7842463cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22175 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 QiDh%y-PuVzTNCF00a`6&o&W#< diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/parse.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/parse.cpython-38.pyc deleted file mode 100644 index 8a2ede01d058fb93fd980320e79c4c53cf9de453..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1737 zcmZ`(%Z}Vc6s?EtcDp@~G+_uE)IeA?(#)WU1sVku$b;P|BAJahmbJ?{0bI_FgFt*k@@p5=GHrTq>e ze_-e8(}m7Gu=;m!f(TlWr2W!_LZ20E#uH9)j2GU_Pkh(*ieT1BIxgWPp-19EQ&`h*PouV7DPcSx=GP|aufeVmztA-DW0E`5Dh`$6QjRa7+H@o{py1O_rU6#;3PqS5+-QE1xq}^p`>TS$GSA- zxGbzUsY_*pDj!b^xjXc2n5HV5$uzZ5n$AiwFR&e_>DTkDXlFFCrF-ChA$kql=>ER5 zZD!SWl~t&N+l{BUT%SRI z%g_ls;%e1!!5jJ``H3CV=d|I~1DNrSc*F5KWx6naLrieYv}njlr-AGv(!kg;$iPK0 zi2Awl>gOgD9{%MbL+1ENqDl5mR*!XF z8OPOfV^2+0d8h_wm~JAbJA>uNPxS&Y9hh<;B;YFthq*Zzw4k=_t1y51C@X5Y?4SS5 zF#%HA84P>Kkf<@;@#yN>?o+7qQ0r2=h1n>tb5)y6jX~5S)UXZO!Z!YD4*Hn2(Kc{& zL(mze`YmAPT2d1>8eOVUuS2X|#muxeI(2nWruBQ^NH?YtWptH>Y?VbUf?h;JFc16& zjhKEHqCiDn1&8t4n)((*y{4iN2Azs_pM#%p}RzYp;20>4YXHK~_AxKb^>t!i2f{Z`?Zg1^xEu%l7c zHqsKHID@;M@9*c|wj5m?=Cdtp1nBx5I}R=meG7Bf!MvXravO5%cfgTu2uLELXaQrC zk&E{q{Q*P_`M|14{x6o)8H^5J3ExfC0Yued6S<2Z4m*hwtAQgOBd^eBb}NdwK?d2px7(DKBdNe*OCOJOB6JuW@pCxRk=*@<+Z<`&&PlO8pn!B>y(! z=285--^`~{CsTIHHd-l5Uk%H^z1cF|w3T*E%XBkV#?4w;gU{2goSV1ulFqaWZqX`A zI@>C_L)MU6w#x3XHSAWbiaTPBxTDsnJkPb(xMS9sr1Pz{?zlDXuCvy;>#gqqSUcRE)=qcQnsj$ryWD%Nd)@o2`{bRW z*8T1S)&r6*w;psKvL14GTf60cxb-ggVe4V{5$h3mkG02rxAks!ueH~GkM$mRpS90@ zuk~K{QR`86zqQ|e%zDf{U>$HDw;p#7S_j=j)*-2*f^j}!J>foSJ?S2{4!ciTPq|N9 zPrFB~BknWSGg4-xb<{m(9dnOc$KCf??{lBEo;6a=_*;hhDU52gb;6yprljPW)=Bp{ z>p7&ytmo~u)(g&7r)rOHOgUAjxG~i*H>Ru?oh{CbxLWo)+u%Rv1$+I)taD4RtbLO% zi}zk~Zgx)LnuMpEo19b5I@V@yxR|#$+MCYjtkbN|d7+WMx}La}# zm!12ZTYGgnFG(oLe0SSI54G z?Ma)bq&~TK8upI8DSId0p2XX`aJ?7T`*6J<*9UNY5Z8xr-Hlqa*4z!&`mVhxj5HpH z&DnU^egv~IkFmz%xA!3b-S%GOH|@8=wYD6~e$U0Uz0ZCxW_JPgFy~R^?6)67$un5% z`!ILRJ%HTD?Ssf|Ay;sPPwYde_X+z+SHGBG^*)Saw>3Wz>BRvzQ zGf2;d>8x$rPM97>ej`keB0U$T%Sg|M=@F!xVR{JZg)m(~`b?PKjPyj9K4rJ;mzxH9 z<0ID%b6-MkTXO42btE-|lr5=zoVo+=EQaqaA@{62f5leKlEf!6od$m+e>Bmi2xoQ3}}bDlq&t`y5uRi`}g07;&|?x0XSP z-fwqNVkKVFek${=;`WOD0j%c-(C2lUZeXw6XMYeq`H=l#wDUpqah?4-aB0;(kNXdS zA{_utdd$f?`MT3$6OJDg4x?fH=t$GU{jo*A*=g5X zK^_(2Svx44aLz6{ZS*b8H?mVpi>ztt+@cfY37@O0AbYZn*MiJ!-SgR-lP3>9{(A;y zX<{fCIq~Fv^y$#E$E<@#PaK>IDmvrv)WK)>KX&9`P}28D4xg9`hIRUx{l|~9|6$P+ z2j6${;L!sIgQ9-STEc2ipxBXvQ^$@5L;Bg&$>XSVJaJPyc;v|8<0lTEz{s0U%Rbz0 zbb`_|9W0UDqr;<%=j?jhZ_d^*Qan%-W{|_&om8!$aL}zcTPJ)qF%pa&=(Igw)tha{ z4i`2UP2?SFb?SalN#tO~f|10%OmngTC$;b1R~U*js~rEabH3wY%yNSc1clj7dqy%# zNZA^*B)1_A=aAb(gLzzATu)|rXh5zQK|UxQ>Zn)i%6`^q1oYrdOK{QK#l}y+@GK((mYuN_6*1y|v_c*b;?jj~$z;J$>-SpvbCR&T=r; za@tL&?bn)~w=^@`suS_O5U)_<83$`ne7x@0<=GY7JXZG{S)%32wq3T!L53R;3&Z{g5v-|4hyrS+Ox!N{$=qS#jk+h0sOp=0f3I0=TqI( zutL_=d^(fzJsS;vpv^xs!yFbcC>n8 zcHVL8)mNMTd=n+HCW_Iz63Oqv>gB&hISlY&owuEnU+Y=iCkypKUGK zsGn~&RTb#4Q+HyrBrok*tgE^kc5KhpUG+O*9ZuAA)Nwo6;bdJALhR{{kzMv=WL|ZN z!<9h@+BjY`HuScEsX3RdOHgW0RW8*=N6CA=9_TueS@)xEdQv1YJIU%2sJREt#&~+& zs*^AGP#GP5aYvDmdwMmer*B8r^t24~Xs7M$Kt5J@22KW&pY?F@IVDZ6%5Gy#F?)@rR@gi-H(n27D5eAD+8v)om4ohim|*Ph8O{fahC~zX zdrPw*1*9T9q{h5McHj&fXdGCz9xOl(U z+7$^k;T%pbo(oEQN&2~i_BGf#yOBeOmN)6GG`Y9c0nhjLArTeqvB4`D;fp~<`ciAx zU8m;O7ZcnO%r<7#kOpq14A207)q;RmdAscO1YL2gM1%*3dA zABTTE-fWd;TTZEdXn{v*a%>`C;AaB=UlS8#OiT))GU2wXN26u(Rx_ z(o%2ey|qx!v67tb?Ndm5lK`pB6{CQE8TrR6@66u6ua)y9c2f`#a(=oC+`^sNP1}Zu68V+F zO0k>k7SH6=bKN{d35X1S201Kau4Yz{r{=r)OIbVJEi?@gIPwrFGW9w-BfH^=p45=s za-=UH(R!OqR-ccg2X39jevz5h8-`B?goxe_m8PVAY}IQB3X~I$hZ4MQv%0-r6H0fGukX<}T%RH~PeIZ?VMWv%fg;SDoP zO%v1sg5f^0KS=7!nhWSQK8W((R)Exc68MnFgQ?2DZk|Sr4RE9-UZ1m%C%&t&J@)Je+YS{RRbmSVM((K zvnFVN;pm~jsJ(4eMJkvQ?KsGTkW)XHC&3M8m?{U6-TKi)F$DbgKM--aE0?M zy$KQG^Qgev1duW^*^Du6Y{BAW@GApu;4+!Y$I}Td>Lf&)@|kw$)kwIQ$V*o=qZa(> zaqA_#-oLc85tQ*O;wMY1kkBmql(~`<%K+JS0Sx!fZtjxVEs)t_@$(_$Ho>6Nv;!>e z#p1)4_+}o~fZ|GNWeCifEZm~j-yLeCPr!bF8j8ZMb5WiRk#Zti|8m5*d$xd>amvbx zEkMiEV5&ZieOjun_sP`UxKQ_?25|c}nhN#=7=~Oel<#jrWr{1IWKN?ZgnDQv3F%5# zEL#ccgjWS~#}&2+)JfYwsG#GCHZM(94~z97A{WwOpLKIj`}26ECuZyj>+C?K z>g87LPWvt&MWLI;hy=00gBT*}JvC#INQip8as1hd9qgO72t>-V)*O0LOmcwiOiavU zV~HMEQe}(lfcCSbye5n$19FaxwNK8Oo_;1aVTKelG@kS%8LG@&An6mjC|j?(UE4J# zsDJUPUMW1*9ZL#DJ!zMM{vK*&Se{O-Ud#JQ$uAx)Fr!n|s$jUn@gT!y6BCte5;cU% z=JjPKRL!9g3$N8+h&c(%MmPzf5hLV!{e}!}Akdn!J=md0>HbSo%>V!6{#vR|63rg^ zc%2ru-E33MF16~(HPrJS>GYcXXp>{4lWUOy8@@-b>TsoLw?&e=NL5o;atRvkf$a7u zx+0-|J3}kjQ7B%d`oZQN)6hs%1LX;|#vk? zYkDiqOJNbXlh6aX8FFdG1M8`E8dfQ~Io1fq zYjB}KlbcO8+Gks#h(UHMZ1&4YKzgEG1=5pmu9|AR3m0B^4>_vAyeU5mgZtfJsOCx< zx^oVt^N@Xv)$~f%FFjV{ddXSav%7m<6>FG<})kjO6jL>`BVpLpw5BI2dg)YJqW1PYW8s{HD$Pu*%UCC`b>MEj1<-?CI%4ksB>~B~drr zNLV5mXSFDBRGlTFt*Oy~(rlay5xrKM7*iAtl}jLkVH(I3WW~Rw&hw=_HY3qW(ZUgw znlRLRex0t!;XX9rBQSRDSIW$EIxY2a*2Uw3Yip4h*JT4mwk4*h zz<>`eoTMPb>|nUB`vdz>y@vO{fuDCbKq{Lt%Vx$Lg)~{gCM+40D|KoNcT@(b4ipS| z59+}1Qo9K!YiMKYmmOJQj+NpkNPPhbjnu267y#uOD`^;h(hDX{Kadhl$b-8fIi}@4 z9inXoPYgV1bZFq&s^e#w*5j z2z-nE&B+W)$v&E!21ZhA6?^u2K~LDTD^P6=Xs*y4zh5lcy-jl^t)@^cFwO+VE4^%O zMlJ1S>tdot++fNh^5?XX`c86Z8GURqP8h7?*RZRXS$(BVuSu)9?C4!xsOi^g!CF?- z>a^z)wFPO&5kY#fvlwJ$8DVtz463mz9Cla`b7HMYtc6tQY10BN2>lPGs{`W`JH-|b zj1i-$QpU)E5|AorNP1B=DrC{LXiTJa4WcWB!9_rBd>zzbxoh@C4w8@WErd(wzgS+FPf6oo~ob0UW)v}v6V(p zK6142IrhD95LjBB7JaAGI9kGq5{g&2wSDDaJ06|{2)%~10!e!^Z(vJ@IvsGB?GbG! zQHizH>FL;vJ3T$YogVi~D|}E-sR!0WL6K44=+`wnDA&JCei`i_5M{G)BD@PD`}TG_d#9S=zp0h?G51kR7Rh2q>zy5Nsg0 z2OucbY9fAkwOWvq$?&e@H`2vmnW4`{>Q%Jg1v&j-aHH9H_6Rpx1&P#92^)>uY}^<% z6rW*h(VV0!5*JHyYxN0|KZbJTeyx-XlICK|&^m+2?X;U&$v`a2VzWU^#HK=|hk6)9 zPg31fjlyIO4wyUy$()_Bv#YS9VB zyfb1gU8EVRu-g zw5fX-k*4brf|$U>JCU>0PYB|AzbSE%Mq|QtLj*?X?RP+2WZ(nDC5bE2rN0ECqNi3Y zOtFQC2&eUse!V}6&C#nvCUXtqqpIBHW>AFwt|QBWaYV4qEHxP;Qj2pHIcG3dt1U)R zfYOy(?Wp>DtYHK(WKj(;HvfI(DN=+WgUGI!p7 zdPLz7Y8YuC!r$YXb)7=oLW4R{V1U3~#~UKchm#N~kAyZ=9yQ8lE={2#XN=*O0|gwz zKMES^r%?iQ@JHFF>x&o^!4BXj)`d{8fCg}STto+G9zD_FETY;(c=+Q1`V)nm#RLf3 zA&FJqw@iW}0t69#aB~TY3K>HD7N3HYxZff@!YeRB3npl*^gD<$(&jZt5~-MGQ0z!# zrj95`pKvosASl!5S0g$Eu{|1%&>m@2ib(!d0?v0#e|kbwOnanFO#bx*obL+#@koHK z!kGb-k)C{)DG?DyQ=*u8gw#l{M33TV1nDs->5Zlsrltq7yE2L0#T~7M4(dvJKQnej zD1*yA%P`VZnJU4UA-NN#4tfy*1tsFYG*XoRWn)&6&~ks58*>ygyaAH{3<8w-u_*fXk@7z(H zf#)E`UA@6$!qK-&D2wPlsuw1#fug?*^jhM7jLC5e+&q2NhPwN=$VCxjTg7@&`HUn? z30RV47ol}v*FI=_kM1gqO>BxixnfeT*QCyABq&}OzWWo(> zTqYGx9}P@M)yCvRnqoHQ36_OgOH3+%mCP5rD7X?Z>eOO=Am%&;Ys zCRj+%#+$jw>xr-=_&Y`3Eg&_-lnt+^oxW(Ul%+P*Gfzuc+s<^$c6M*-Eu;OUJSm+q z)gRb7JKr=`%Ki|f>eK?H=#^o=(j8tHu?uz)=GDr#)_S+1ey3Ym80{9D2HGp_O|=n~ zt-cJuY}p>d-LFX7YtEQBiRjNEY8x$&`DIbX*P`{&?kKkIzLhopcz4ZJqaIsXyD~1L zUK@{kTv8*K)^*32ddoOF=CALLtQvM%TAA;T*u#tu$IOiAnQ0%AUfjgz-pBk6yjwM1 zH{!9v$1HPQ5f5{j9_DM!HQpP+Z{wLXM)O}WZ%ErCGH>g;>zLPF*DZ@-y3F7*`lTmE z>%&-d*_S72_>$mKA*-QTm;tUkB-j=afHOFla<1ylixwh&Ia;Gcwr?!8#itx<#e?<< zsS>(4NlI*=ARpF_5;3b$UKF_+MF@K{JyXGuHs>9tp;7%T zvVvS^W&uI7>UG>4wbq2*8JJ`7j^D%ylJVYfdbuJTEACG93c>dROl%U`6=c2nI$qw! z{0V|P2<{}fjbJN4us&QkEK1AqJMC}@#mKI1XE9OqMaM6~n68CjC6ciS%Bw81onRfo zPZ6902y!qyI&IkE;F(f)F{iR0fwdS+r+rYVj#58>%!&0kLW3;U+5oW1V$_Rzxx)Mp z5YYCo{sjRiP|NFj`J_vM={2mP7kTKc3X+LswMKE@A1m~OtZRVKb6lUqWXtK0)F_O8 z=K5YBC{u5j3zW!9U;t$p{}_-`xn_w>dK7*=%JUgmGWr5a<67uoKn;U!80J^YMYNIT zb21y5Z>S)`1bW209}oNe5i~c_ph7`KM2|l~BDRg>U>m_ncEqV{@YA%3AfS}i5mOx^ zRrj-`cA#}B(itpHID4#1fNG}}iVLO18C-`zsbN2ncZ#5@%b=1=*hVz3V2vZ7^P}Bi*lB*pUjy2N)WR5OW*%JO*Sf>q z0;$&7-)D+FF;eZ4)DWMz>6V3>73xb@Q!|l8zPr>+svM+dqV7t7%y&eCcxpmOT#qh= z3dUemNNk~u11@ZcX*l(u#o)x2&?UpO1cN~zdS|iE`YZyea`IieZ?x2K`*z1(;YH!Q9US;Ja4JKz=tJ?k#OLS^d>6runBv8em`GLW7xfLMWJx&SMXqv@Gu~fl9u-{ z5~kI2ofSpwaO09muj1*SfZGVWc6kdtkUaf{Kz7I@*--YA^KZ|m+7D+C zs(z-VmJLWZ297WIaAtHz7GPz)j2-)Y>c!OOa%VR`pLz&V;mXJdMqWTp+k62h<{&NV zom@n!A`%qrAUHvn>kchIY6BcnUxdt4<~^UE-7HU|XPf0&_ykmklIkDQ4hu<(uKLQt z$l{l9g*?ZTeeDgPWH~zvxpcIfhh$U$%^9^3f+=O!knSLNi(No&5xJwFJ4K-|C7d7* z<)s&Ks_MEjQK-K4ksY6BeB0-N_d>XeCYX*1wz$W_l zd`Ieu1sL^N?NTf#eaTMAD`(uO5 zw?_*MS=b~}2&0E`a6=XV%OC~tn}85#1r>4w>jeGHkV^LNc(y_PG>4z;ct&x@@&R@e zupY(6a?Zh&;{lT>}B{kQqEq2nr@RpXmAk_t*131@2C9J@lMh_4+3fnk~QC%p60QB zuxBlWhhZ<8K^eknX0eCkKdgg9d2@}tF#tLHRYHumv5?Xyzl4P2Ky+4|VL;+36bmvG zUk9oC^LR4LrPVWzb6j^_gKs5#2`$O%2spnJVI2i~_~xW8d3}~IT}v4LB|JFEUbEU%uAI)KAr8NtD}vjQADN0J z(3PLUC7~Y49`TrW9d1LMqikBjPjHVF^lS{o!uV8ncvQ+xL+abduzH(Lam{bE2Aq8p zhn>Kuz@5OCo?9uQ6bxy?k>V1NF(F~D41*`6yJg`f8Fj%1F9BD$&>gaK_`(Egh8A5! z)Q#9Fz=Oi`+h-5id9fFS8nRu0mRzjwkEp)j=sOVc&_vuv{CNiVy4>QMQ2odrn6R}y zlk^fsCtgFxS`;BxMWi@Q&*J>=$u!y`msG%;`V3_x1kzd#y_iIn=diWJw^gd@)v|R5 z?7)aWkh8F%7(6|VQ_e`kGCMsjU!-^m!DDa=wf)oYeB^QiutK)oD7W3E)a8^yWK`eg zv(|)yE6xstGaGJ1^^17>TKn+B#Asq5&r=ps%MV?pAIFZMu*PfcOOaK3YB^6!w2n2b zEX>l!BurI!)fdXe%6kk>$fyn*c!a}#R~B>r$C>*etD$bJEJ1tWZz5X%E8-LK~M zbD7|_cN}hq6SNoAi~b8vQw9ghCArX7a|nkS&}c)QwVWw~Bb5#H+w5Nss||)6WEdqC zv3YWJ7-^R2?sInXBPPu%eP6YKX#p>W z$k}(i6RQqklrLVZB^`02z4+)m_&fU8U;3)yBrSd+(L+E4J06C$g42Bo^Q?8po0y`y zhuq#OxyY~z*OSWr6Q2Gn?g$!EQu(sE75J@~i;tLO7;=_~R2QZvtIk!9{%DGcSN%cU zbPY8IM*!CQrW6b&nf55|%ms*CI51=|2LjZ+I53o%!yOI^@la6asCpIes((cAn*dPs zewUZ5`aNa|uZ>wR>|-ML%fY&S5}+Iu|J8U%;N%s=z)Ef`0+Bw_+E>I+koD`pu~<5U zi1cta|Sudj@Bhw%RI!d8SU`~+)g z&qla*M*Rxx_G_UN!a5{9)BP&EnM1$IHohDPd0==U51v1)YlKCA$X~ZgJ?~Cf=!X_= zLX8z#-&YOMcQf76rH%fkZbinJSjHm)F@^*hS^x=|7#J51Mz!zR15s!37 zQ0G(K5j>$xT*93NDJ7bPai3)&g&^uEFYWtieG5i+D{9j@U&h?>D>4`-bXjVsU-YY? z?j4T|a?Y9+_#hy=Y}DQc_$Z*UVz!FN5uXI?WW`Ijbw{P|o1n+?ZHxtei}AQeTW!o6 z{8W(PUq>Vp5O8?;x3vs^0~+h~gq_e!5X(H@g1g{4vW^yBLI+?^c@UoheZ)PRdY}DD zh(*ts7MiQ7KzE5U5nKCmG5R7`b@>3kmEz&EBK#~4pds&jO|X9 zMl8&+0rY>wJEy_#u$@1iL5?x4RoOWl^_@w2uL}+y=gYBtKY*RnU3Z5nq zNke1`@?0ILKZ;aPgc*$AaDo+VGoO&*s9z-zg3)5?EWsH9ZgcfG!50WV2oP+OGaaJe z#2=K>yaBX5QYd<6xl4TUGJ#J(N-JbV^aP=q+O6>8eDHk)G+1fFTuEj?+y)ctZp33C zV~^z|t!)cY{}I$_4flQV$|{PwCDi%{+2jntFA)4^g5M(eeS!f}`SZy84U)?9NTfz^ zTmX^~WuZ*JJXBmS+V~jq8L>nCo2EOQm+5s&F{_!_9e zU)#t>^B#^Sn2J4ukikLfS-MKdKzDnZ)x)^KF&IO8ZIhbSszE(!0Yb$B4$LedUJ-|B zjD-Sz@Xo$T4JUInW(cST;$>luyh#5VuzlO3g^&Djq(?)Rl72_ya(|hqe62*T5 z>4BLIihHSWytb(JJ(5Os3FTVE%k2#HZG1cU{;C*tmoH|nf`r>;89;9-Nl{ ziM%KKR{Xa9)8p4z+&(PCyD~AHZV8=(Fp)aF9_$$*zeM#_o+AU>N}gu;6ZYgH!N4m0 zUF1E*?r4pW2N;&OUbjQNqYDs7@Me&P0)ejt@T-36O;-OT!GGtY3=3=JVF&IpCx6Um zf0JOK6P&XH?1V-Y_zgh^X!$GQ$7Am@tHC;+?F~=V0h6I{AgmGJiR39jahf8DbApn@ zM}11Y(_!JsEKRzF3JTTWR7QUsKP^Yh^Vp#`jE2T1*#71Fcu+mOO&5qQ#%k)LX^8^C zw}Wj&a=d}kZS#7klw(U>#S<~8Q5D)$ai_Wfb&e*%ZP)q zi=Tz`_c~540rN`rUyoFoCvZjqAH?bnK{LZ}OVh#M#0LQ#o?s(8hNhtvM;!vFbuq6x zlRUShM^BBRKS;mV24dOzniMV{MJ7c`lNeJVbuj1;?Jy8xdip@L9FBd0c_Ju<5pTVA zrT*w}9Q}8Pq62z6s*4?uU-vkt#~BI%a-3C0*BiJVVL~dnx-G8o9(~wIM3WSb3-dmqq@`%)iRuhqH@=EUj3$P)UL|MBczLc zyEr0mYl&`K0On;Elbc-N9tJ0Y&=2PHefmsNNL@aOk`Z*D>#@T zrqd>ORAlI>q?YgFVWQrE^f#`0i<6)`Q4MH`{N!rlTtF^=()*8KEa)}p4m4ZiLW<{C zkxC;4gSnhsy&AkeS)MZbitMKip4 zzR(TJY~)6SWdQZD}{ z-TAC#jVK+txSrpN>Ontq12v6Zx2Cl|)GvSBU)SJC-FsovplcB93bl-P)8RM@{o^np zIhzr5rZhirbD`c;+$IhqTFwxhwGD8`@C8ReGha}4T_xL;PasMXH1df23B&&^7H~$IP z2#7Hg>#kZ{06Zxc}Q!bszc z??U?u-me4+lIB0!*L+ns`XOA@hb0~4&cH`G=V{u4toV-|dYb z5|ss8)b}v`5rQ`eE)aYS;Hr7%7-gNQn*uS%d$eD{Tr-HAhA4~}_7rOrDGL8B$KbSo zjw2+^r!G+8Gk#Mu|{nl9=2*O8IvG&ji=b~@U~lM_3& z5g?`l+G=_~-($mSKf$8_ID^|hr>G{WKO*=(0@@3E`$}v7?`Gacg1rQr2-Xsi8mTb? zLF3&_Jw!l^SHyiSPfs$nli)#u_Yi!7;9UftBDjy>UV>c&-wy!8ECYGI!uw?cN*HPl z0Q5v|5(H!Fk7s9O6B3=^!r`YeR1R2Wl_5>W->=ZSE2F-~N<`d9v&<+xVGJ}11#wRa zLO#b*EYRlUF5oU@=DuN?z=?GEFHC&QssOnjK|A>LK*88#ZlNz9R%OC5*af!23a|lo zh78h-Al#JRf;7GRgorgvRlbqSWQ_G46huI$GZ1@$L zE%@vmr#kQZi{74H@mEfFA|lG0oOfD_ZoR!!Z%sBkyOtQH5q|!3*R~~mG+5WYQ@XJ; z(G7f;e=Kx|C35v5_fY45VA6xk0=}_~!{NPU`*UUwCEl}u$DTE|)V^vdPoStOV-+OsE$ z;d$y&{JbiFlj8raWSO>MrJan858z$I=kK5^W~{8u2$7svCYRqU13ih)KR5kzw6{9) zL3r(TMi@tEfz|klz$tzwR9jsmhYx~7(Vph3(mmYqk7@o6;O8;&fc}@7m^?H`HRMG` z%kWgZuBCt60lrMYBh|Iq7vsSj%VTi_(q!})qq&S0)IS6W%C*{A;5pX`hdlDN8a4n- zvTw4$I5Di(NNWM3%0kaMzm%`$`-|2N*=O7Nouw-Ib5*hX+W!5sv565K_wonV6C zZUUO?u*czgRkW{Ih0rPNX?8)zp}%M7X}%yFLU_gfeEk6e;VHs)gaHXpd6*9#A=pFk zZUSLm!h0wji)~Xq%G7>>#|RD(JPr_Kmw>&Vjww6D+$RX0B=`w}!vsG`@H9YBf&ZT0 zMhQQrW{pSp{J>iDJu_=$3O-GV@i?X!$Yhn{j1!J8OiyFfEGwQP@CiOh@V^QEl;BeY z=LyJmgOOT7A*P?;<9zfQ!6^cp;HL?$5WGb2If8QprwM+U;Fkz~o8S`!e+Cd_7^I@b z1G3r+eSFRB;JDU5~G-+OJ!!x`prfr(eUNXIa0| z=I+dFBKUBo{3)b_`1QiH)-zm3zLc?Jv`z_MS&^ z9Q9(Uy>Iezkfl+qomazL>MGH1Bc&^^Q}Ev)mzHm9Z(C($*3V)n%_0%*3~+bKEQ?Zw zyML4bGCeH@MIJ}PFe<_lN};8dN2-wKGPt@q-e$f1J3AE}VdryQp-Z85 zl`Icc+9yXQAFXYS=NQEdh+w5PvQF90D7Rm1fM9POx3*zyknVn+2^oKP#lBb5ko1}A zV7j!_0;a2{n`M%3=7W6wFwLX>ffVaUds4>hpY%kYKP}?Td?=!{9P~HKEQ^bce5jYh zU71Q1l`^CNV8X-~rcolvM8QEUrWQd57Fq?sRFmk(VsI>hOU=YZ!oF>MQ7aHs^B^}t zP6BkmG(mob1?q#xR>DruOCu(%15b5Je!@z7#7gIs7f(ivKsaF|PAg&WaN(SDz){&! zCXq}x`%04M38At9cf2rESyqOjUkO^1U^kLzkg8Ski=xo=0m3ZGDD6vaBjNWvH)4dQ zfmC(rLK_&B_u!cWyJ&(~yvaT0usZXYdQ8IXmG2lNw2fN01BU?;668BUaRUe0pp1{W zVCVeA9svTu&)GgTfW4)bajw=td~QsrhqN9WQSZ?qVUEX!P%zmW`);Bj9gKo( zTCB+oM>~h*&ZjTXM$LYfmNG5PW$nqdp9xfguH@7xx{3bEj>3GnBCJA@X1qU4w;uiaB05##p4-+5=Syq|m3#x=TC5QbKRvpc^l z*E8o61X%B144Ag~pW&;I;Rgb2VY(OKIx+rxfK4JO&tqpFn0;UY5Fj`N0RjsW4}t)nAPM40kl+#`z*qAzJG<4pJHX8B zvU-*PM!S+M&{8aiwqx0HB0&~#V#`MCM2Q{8N*o_2_75vLiIP~y=h%JX<3vtu!;upw zN^FI3%zWRi?wOw1*(C_kKG{8er`~m|>ejuts&3T_{r$NF{u-b9)#BHt5{ciVC;qn` zo(3s^0G2F78}qbM+4Qj%vXzh`+aTXLXCarFxfpS9PnqwYtsS zR=wN3ySm-oUftpDsE)Z~)t&Cn>OJl~)qCB0tGnD?)!pvy>K=Dbb+5a(dY^kA%IQ=6 zYCx?~c{Qkp)UX;+Yt^V)r`D?t>Nd4eZBnMpfaZBuuv?P`Y_Q#;i? z>Rz==?N)o#UUi?^H?!T{=M8!HZ%DZN@p}Nj4|wan`@I9xHrx*)>_PlKgx`np`v~G5 z@g9}9gK!`89C1G;c^*bg5~&{d`hLjL-$ZZRUwNW>$UP*j-(PvMde}WI?gN!0)uZmw z>M{42_#eOs9Cwdf32)R}uTUdOIdLMP9#VsEC)A*K;BwM^N7Dc*#{Ves zRgYeA)Il}$cG`W~Tc;koY`M=M=i_P^IfuPd$oZ_~d*X_X9M5b>gn0+)M*c&{|D+m0 z{&D0xtkxpmTJJgJJKZ(kNG#tGHHv&6LB6AE9rCU7?nl1ofvLfj_#V5G2EGR4htad6 z>}_@YN=BVf>yi5mazCZ=$es6|NA9!eJzM|2chY^KmPg!4wHtA}y@wI^0{l;_4e)Qc zY`ZVQ_l!CP-zo1U#J&vwv+6eZZ$lejR^#tD?kh1&EcKk=!oD;Aqa0Or8n}E!Z3HeZ zN_bvvLJ6C^S5V@s@Sjn)!+*Q@UxWXw+5`U{@xKoL3u-g`o4rTF8sF$r;tD?n12!rM#iGqLi)PM%3!TUsT)R-{yJnPs2Z36lKullN?KKgb7uKKma(ZprznuXbBU0qO%o^|f6 zYqomdQ;_UsRE~SthP|)@99!~7Qa0;??Q2^ zQu6(=fuR5FE2obYk34nk$TKI$PXx&)YnOuTky52nnyh$mG1-eH9XLnJQ}w_(Rrc#a z_PP0bd9GHf1Q`@r_jD~tp7H8I>g>WiGC5~2&3i$HkU3K?)Q~uErb>RDSiJDU$)h(c zpb1af(|S((V|LJAuFlWtdeN`za&0D9voNnpb+1^PtK+MAWBFjsr0FE`qP=h5v&?;^^HV?Q9lt=9DWUc8=uwyYI9%C=0^i=Ehx zgyHQ-N1^RyWX92vXX-lWq2n-nGswbkTzz4z@%11a^)Yq+h;(zQT=P_z2^~Kv+1JG4 zgfudUVvhv_u^7@u8WCt=dpJs$aQtRZUwUrxoCg|<=R8?6InlhJ_w<}!u9x5P7}z`R z&6FZf9K+)r&LE50q^pAdD3^)okMbGsPz=j(!UQ?w4e1253u3*`{M>JT_M4vrLH2mL z;&Dm^{YT3hn9u1;;&q<(LGQhUFX__!yoVk?<4tK#y0h0fO;6@bHy@sxt00YZxwOtW z4UU7SOP8u%t$w7W)wmE}kY(;OAT!S9qosPu%w{XdJv*no%JDK773Ng#aLM=3!s+r% z&_lPxBF|tn!B2QKPjfPj+4>Boq&^J*Wv>0tf%gzT|78F#LG8`8Uw}sECY9|vUdl_W zrEHSY3EBKir1C9RZ=Es2x8~q{z>Xty8kd3}>jgKYu z1|-rO32p;Gac|JgRv9n>S1?p8&cxY~Uo6%U?xz6~cG^l?jk~%a+?faRC0i`kN>#5| z406(-1+dIw&{r(JxlpQvF?qj(QA_6sy^)yVlvq8 zN^?09BvF>mz@Y3)2de*hq7IaZ(5XWQ0oN!vOO5-2lGlLW?`jsPYu^M4)q4Owiq9ub346c_th3AJG;uwI&;J}iYfgJfGoQT-=B>rq zi`i;pZYN!t&*I1YhQE*VTl^`^_cU`LZ5r-=l~GyD?;e$t`90wEduzPBHz?d7sd~W; zur89gA*AN|Xh7w!B)LYC&|$@18rFM(+-}lPNzY)=$7RYEA+PJ{<{7M zO1Pd3tha)c@L)3mNchnoiH-gv`22GKix3m%vwCRJK9}%^$bjnBqIKC?vg)?{CNT&} zr0LN|7sY)(p^w&`b14b8-myMOuAP!7M=FFdfkqTcfXlA= zkcDp|mFbcRxPt7#N~t=jN{{~xeBZ{GXl$4=3hwTMmAR=>#eW4jGrL558$Wpg*-ZMPr=jn$FdIL^Er9DGiYJBmMC5==4=$P7IUUD7BOcs>V7I> zV9rp%x-e&3<-nYKRbP`ilRfvVHDJ!z!U~x))wLnL4~S`w#dzlcon_3eG2sy|gKnA! ze-#yVV{BM)e3&d)Uu1(W5v;^w|7i@9LX0#GCY>BM-{i1}Z!%cjKp|5k+32s0sZs%@ zIx8&Huu`&3?4g2%?h^)SgN5#^C(k(&9C|vF!aO}n^CA^JO>Q6AIka~-oyo0cRhEFuDL_152E0OFezsuk+XNXB8 z)1PEjRNhu(g!(dLMKG?;2#H|~>lW&y@UP%&GQ#{aM%d&ytFpP7_h)nZZB*nAx0B8X zXKI>^TYs8BxJ|1upF!AfF#P)g8tcKw(2XmzF`3EMR1p&!^ai+^1Y2wA zl>^=|OE6FkAT@U3g@KL8dUH_k2YScHTWWqVFtwoTrE(=?KtW1-Gv3ASnj4owN7%?M z0P$5OCRTE8J>fYA6HE>^z%QYrB(;mQ`c;4+gY6&goQ$C5mSf)_laX>jUAf6+9Qp?M0S zz&N3|7}b+*@V_loP3it#tZ$ZNYXB-JIO)~oB6eE+NC~x}d^R~G2hfsn0h|0m6l~Ze zM=MBGOZBN)E!?snC_hiKF-j!|^15vl$RA}cnN6)(`B{Yh5x#IdsVt_k7R}p@b#YdJ zZisqvY;A{v7+ag3V-2DXzDSp#DfC2Y(ftIX1pY8x!W5|&#dJcC-XQ`a7DKj$F=x$h z;`7%7gezxYJOXtWx?#$;@@d<;o;FxXMK7?Zc7)J}vcz5~zI}nsxkmM|2cHb=y>LVe zY=|{yF*UcoZe6t(Q`f+0-$^f}>)4vAJ6Le1qXjpaQ9FOFYvHe$f^&!qY>i#(sk!Pr z_Vx5ULWDuQFQ#uYWyh!k_d6|&OCc!oxl@hj@^_&jf zu?ML$Uan1N>=owPub)A|jc0O&@DH;BJc1jYh5B3p=L>Te3e$7CFo_VqfIa%D*+NNs z1#IyYxRBp9HRtImPwj4&Fy5UHCsB{k1iNn0ItNjq?00ZnBKv&F@gT!0yiyIbR|ZuC z;Py5QmhC9~2$C<`QE2uD zxA!QQ>egjj4^YXggTY-(d=fK+@~H7hvuim<$7=op`oBI~suwPJ1*~!|g~KF6)EWmS z9v^dpT-h(<{H0XG!HUB)hX1W;;cPhIk9BD%d!WFEa%Lw|;39ToxRtTR>-st51jz;zn+w%Joy(_XX(&jL$r~a6=9LFqbxwu_IcD zmr%ZWy=p5~(ECF}qpbp~l0R$|Gv5{(h2u4fnR%VCa}5(hAEm+X%rpUEB0;>N=w z?+azWQ1i<5Sx*;A1(Apab8uMTahh*PEImE=yUcbi;o+9>3{nCs#)}wzMtvUWeGA_oSRpnh;VPxU%e=Q>X_PP6Y95zyw{Sy?q>l5jYYy zDcq)9w}$YW!*63Ss-;Ek*!Sf|XOKRBfxqqhC@hCVgF+L};S>Fv-6NYBQZ+Y@eXlaD ze**FPCkfio;#MmArC2=DB#$^IQSA6wu4Cf4Ya;!lSgKqoUGmKY6n#PFo=i4QXZ=&{ z^|pi($^9PI8%{g)1gG54fV0Z>2ery*+IdM4Pk!u%kqptQrj>n-OKR*lO`6ZI^%*=m<~rVOGl_&~o!%TMA|mOmrRkr-*Y?*`dfrBG zL{sJ*lXMlHb3pll+njM^#mzM-&p#N>wP@1Ki8~|iUU6r!wbqAo4y;kbQ;r^pf#`%Y z@AYwI3Soh>4iOB4a>9`p8aOU`+_?U`KuiBUg0B$#eSo01X=pGv-CY4{5^J}GDAW(` z1#zcGtmz4bFnD zAWoe1KOk61!+MpYL|si5uQ+%M|KDv}z~ad7)^x4{3Z~Ar(gL>0FhSFzJ#R+_y_w)n zf&zgeXy=@=jXq7>MP*5Ht=fpMR1LsDt%;?N@dPCHeWk;U9^n&uV>C>dlTnv{Q&lv z?8iX;2#4TrhL0mW8HPJ19H|vToiG&J7)*`O20~MhnZ;~+T>m_<(EpI&9})Zl!7l

    IFgCsap;9#F>mgj@hE3)U$aAXT8v6DTgdxpUB_>uKNe~nwLh^5kB5yQS4xar#o z?j$G>ti-T?oUIXtEt`vNMk^7{x5To8<_QiMm6Y@$@o!SZ;UFEu5LqP5so8GZUkq!WIIyIVnZ`l=gN^L;cj8pqTR$Sm(s_(?J{yx9g{{%fZRX zFsyRyrd7^}Y#a^iCxB{qZB@+m6s#2LelQRj+s;>Dd+Xl}j}0l9JMywCk6)f}c4)Br z=TN`?D#7antzn&@w*>Gt_IOt%b8Bn`5?XxT8sDPISeLE6xSbs_ZrkpIal|HKbtgfA z;IjlPF|2P8an5LCWd|KIZZ*3ho@tVD4FC`bT zOMX7Bw{m^Uok94M=TrLedXjrGi^+9~B`mO)QnlT62c~P53C9u2YsT*&9sC0CsJ(d~QYtin<*$aU+9$2-&IxhSGTfx7IK>Ylg`~-a$ zX0b!~ z8J15SGlP^Dkid4pk-(~)=1Ez*&q`A zGH-~4W7scd$^2)W;5A5qIl^zsxr_WxcwImPh!p99Y!eEz)vk(`2b!Cu_T2S#!fl-5ro zi%i88j&NA^5thvni;i$G#jP(SzKAXMcd%6~+rZAaIcvuK5NBbbtZ=S6j~qc72T9Ou zVSx21dIyV<>0j|JPy4VJUQtdAgOo(Oz;VwyvGrdr44_(1qu7=~p8f{CD=y7jlTKU{ zOw1n0vo0!aIB>vPd|3};I7|;yZpC|8dNHXFBlt!VpvwwWFzQw@Gp%RE_-E>oJh>4rUxP*}L zk_yVw6{~qtlSS$tucu8d%8A0$r;nk~6=;_O!VVB^Bck2d@nfTB8pp}IcshZTzu!Pg zW1+K>=CUnnBq;K>=!VI1qP&?yBQ6Nz8VY7q^DclffK2MUh|m^-Rn?L)Vnx~wjsG{s zFnfPh1esf^2(dD%h(7|64O3t+!_W#%40!{GorR-}OxZ88^Nb9}HJJJ=#P5@=+Q`)( zLs2n`oS>J@*weyRB-mgR+emI*@9mt^D^6$GX(M^9EOAI4TUlox99f+7(?T{6ONc4> z+y4G?$@Dntx>YhAP|+PGp;i4`C~I{}eTXgQ(1KF$XuARRmqf1mw~3P?XtBBpdO1c1 zTZ1lEM1@Y2K14dz0V)KAra__TH$$MK5rH-HAM?kM%+<&o2{Qh5KYsjSSiRbf@qMj~#-;9LK>%9Gs(Ug^H7# zkKMKtWy#HzYq;AcmqMTzP*0Gi!u@5s{{um*krVI+y>e?q?vfOrL&b)=t;R@%BM2K* zWD;~atfJsHwp8pX{T~ThRkQ}~cM&ljm5;+J`d4NZI}jW1OsZSmB$|w8N}pii-A{_h zeVY9k$*MN}O8*-qY4o1MnC$Xlu~VDT{|+ImGlH{GQ@{vD*;UKuKQz@2`dX3ScIz;< z=?rUO3&>zs?yY}?6j5(=9PP!nQE+4@7Zk&ObU>ES21GN!abCyur9Pz2sYKhgrG97% z1JEACq|_aNj~AZg`jWdQ^x?4w5PBY4F@tI?YQVD(@DE{Ag=z5s1bic5T08{--`dcJ zMWM)_=zoyXno3v*iG zD2(&N?YW>q+t0!B$0#Z;0>xTYzed+eD$DB}8PdMlGB&1eIMsW%v9WpWbva4gj0VH` zjuymrS(?Xp(EUYY;gVrRnJ^pC49(7A&lO$5HS@T2y_)w4e*^_B+x<@>P$Q+ongiGlX!b+LG1B@9gTG7KorWK;&= zAbn_2)VWT&o*ZxFb~gWlg#LY`(f@^@qk5P>fW;Myjacot(h%O$28l>4O^xShZ)8^a z(oZOie{?rHgLD|#NzwY7`)N>f0nY<1LmWv%9GuTVp6W=qvHI_b?L;+QEP8Jii%T&~ z^KncWxvZCnp7atag&Pp(T67A+_&DqN1A-Mg2bXY)#ZSblZ0j6}T~=pP!f;=qp12Aw zRJX5T{f-SnykbGK!|}$EiLl-1;N7b1V}JP4jY>tVw0PT@h-g%%JY`EeLy1qs5 z-w3`$@IMJI6Z|Q`{~;i5F=CS$GQlv?=qp5;j88VvLi2$VAUmC53Pm@JN@uaU+1Hd#CfSv(Yz#lzl6OcqDd*T~{gTq&WPHnMnKD2ty)yFNTw ztiOrkRu`^6$U*2TTyHmYwAy0mxx!JWF3j)7RgrqpHavMlB`CG{9%{w;7t26tHnnN+E(GM$pyB%+l7OW?EE3z{(l%I{&Hypz@5}Nu?kZ4&4--@i{d^23?+jMo% zB3as3Vz`8QR5T?%uvpapihD4to`|I3Bwy6|0P;}MweLu0k1(8S6K7`NT z2@owmc{;-PabPcs^Lm`&<3JMvMc%=|nOzpzP*0GLz3y{Z!veUGf3oV~u1u*`ICc@* zkng*>XYq6vZo}XKAlG@Z?3c7CiIb@7=JgZuyso6p3H@uaQCr`MQ8cT^mz{*bT)paD z2C zIdYS>-lSp*60>Ch(>Oxq{TLQwWGQ=U}S5 zjMsC1e}nYGq7v2s{u{T&NY$8=gI3L|_GY#h_M@Qq0g1Wp3Z-65IPe=@d0pY+Yv*0p z)(r`BE+1@&6pmtLVYXJpt5s9yjg3J(%Di5OBh0WPR#Liti;d@sH!=<3c|8n7wsz}; zP9?03PoSXI!gZ^30#|3sf;k07jpwf1T^+&79zGkVux53CgHtuIc4D{q<8ZYGG8{KI z2ihxw8Q?vv4pAMXP4G9_2%|Yd4#inbIDRG>3KSZ61=TDgM52ELpIojCkCFy>loUQ? zK<;6Vk7OLo?tDLvj*ikMLpJ46{u@YTDrs@235MlBe1AYRh0vhj($IT(A2-L=40aoq zR6*HD!SWMum<_oN=;S3la}vIO1K}_V`x)G(g4NA>#2rn%esC$pw2Rm*N7^(DrjcgR zfg$KASPj?@)21e^99rP;_aXZ2#q@)?Gxg?^Crr-@CySHr+G;-lsyN(ay3DV~64>vtuLbaCys~n`Hhvmk1xs$GRFS7nIM~nNOi4<*C zvan92)w|fU;O0pmL<`37o>j)MbAGmsCP%V4nv?J-j3T$sNptv;v$UbwpWNk~BCWX;E4lAnmSVuXuzw+Oxr}3TX)*xZI(wmd^1eEt$CAy43lBMaEqxeIHlqi)97lB3wJdJ`4sblqbaYx+GTH>~3?=o$rZ*Pg7&R5~Sm@c5h- zEeK+wH9_%Kb3*fGZU|!hfE&kbHZeF7ZMecP4s8sqHkbL z2KIS;ReUq}>XWWLkI$QQljq9-Re~9UI>9`FSDtJmNMhLJLwCbd21&lY8J3*jM|jY} zI-k+tKgP-vikbac`%NCQ+Io~dhmWt^rEv4!(~yt$?!AF^UVjw9v0j~kH^?32^MiZ} z;qkqwRkl>pi8M^ja|yi*1vS>c@tVJL$7^cmYrCI#P2Dplz6H};)Cm#+sH*zJ*XIG(Rb}CrtW$DRf8Vj`u>H|mc`BwoN z1B;>$T!y3w??hX;6TQXUpEkFic~jrWl53PT7+t)icesxGrPpYsYhTS=OJLlSyoV}r zE@YC^$m1@xbG7Fhp3PZG;dXWb_pNg%`!nI)?9{nlq>tUrCMNYhTJ|ocM!>#giyn_t zZo?Q~$6L({I3dD4^~*pz$UzP*7|WYrfNSpXt!5nJ=+7a6ndIce?wXLNNBtF~XY|~{ zypI=YUpafMc;=*g?2O)tI)dyo-X&25g5i!lcr_X?N>B4SU+_B-2JB$BhsQGV-in*{ zahJKI^&XVu_7GQjmbrtPWk>vB4&!FzPrx*XYlk%6=cBnR86eH^U;vA&*^R*n<);0` zaTq3KLId07XFwU0$Pt#&U4&!N(wnItU_k`h=BcvE%%qo+D!b&=)~g7~!*23ff)fO12~HCnD<5t+dw1VA4SIe6 zN%g-#n{W&8%lOd`GH*tevBaO#Zi*d_&57wUUIH)D6C|Pk%V=~AK`=18P%YI!DJ8{s z#ZPlIcw&|arF0svedOrclTOVLl()5YYURG!i9n;xv zyFSPF++>e~r{f`&^)}m9pTny{$MN>@Gz*>~m?daQ$lfz`9hp&^!yS>bvbpjIQIcVL zl&+SjZ^=fo#{EQrypN_6a^rqcQ;maY+k|4P7q z4pIyCG9F%D#{ilQx;fDl`Chee-Z7Tb|BZ~N`fqN9ahA)QpSnQTodjD5?jqPqu#Mnu zg6#xU8+aRD9!4;1Y>eT5PQV>KeGkFC1eXcU5lFxPbGrUD0p7nzKp;hrabrjFG=gE9 z%qOdTc|eu-@5(j(Jd>Xxph$Fkx-$SsM;68#MAlOGB3gUjc z4iM}jc!uBsf_Z|UCZPJLA0l{|fHOm%B6yVGAi-k|kR0)3;(5&jBTg`{^ePH2v>#32}3rin@>$jbqh7}pu7rx5HnowUd zpWl+sI{7U-viUo9Wb${#YW&|6CawSUcly@m9T+4g^XmsT<@-ipDBb*j&xzaJTj{^( z%jO;ak8Ep|U@tFmAWU^Qmddif(_XV}rT?sNFdvqfAI=XCIQbNgZubrB8_MNhZOa?O O*#35U&3bDf`TqbG93PMX diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/typing.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/typing.cpython-38.pyc deleted file mode 100644 index 203ec6a21f7ca1f65f485607cc91423a0101e0d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8515 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 diff --git a/env/lib/python3.8/site-packages/pydantic/__pycache__/validators.cpython-38.pyc b/env/lib/python3.8/site-packages/pydantic/__pycache__/validators.cpython-38.pyc deleted file mode 100644 index b731c72723feb3196c78f0a33f7e7b8141e58657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15787 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 Callable[[AnyCallable], classmethod]: - """ - Decorate methods on the class indicating that they should be used to validate fields - :param fields: which field(s) the method should be called on - :param pre: whether or not this validator should be called before the standard validators (else after) - :param each_item: for complex objects (sets, lists etc.) whether to validate individual elements rather than the - whole object - :param always: whether this method and other validators should be called even if the value is missing - :param check_fields: whether to check that the fields actually exist on the model - :param allow_reuse: whether to track and raise an error if another validator refers to the decorated function - """ - if not fields: - raise ConfigError('validator with no fields specified') - elif isinstance(fields[0], FunctionType): - raise ConfigError( - "validators should be used with fields and keyword arguments, not bare. " # noqa: Q000 - "E.g. usage should be `@validator('', ...)`" - ) - - if whole is not None: - warnings.warn( - 'The "whole" keyword argument is deprecated, use "each_item" (inverse meaning, default False) instead', - DeprecationWarning, - ) - assert each_item is False, '"each_item" and "whole" conflict, remove "whole"' - each_item = not whole - - def dec(f: AnyCallable) -> classmethod: - f_cls = _prepare_validator(f, allow_reuse) - setattr( - f_cls, - VALIDATOR_CONFIG_KEY, - ( - fields, - Validator(func=f_cls.__func__, pre=pre, each_item=each_item, always=always, check_fields=check_fields), - ), - ) - return f_cls - - return dec - - -@overload -def root_validator(_func: AnyCallable) -> classmethod: - ... - - -@overload -def root_validator( - *, pre: bool = False, allow_reuse: bool = False, skip_on_failure: bool = False -) -> Callable[[AnyCallable], classmethod]: - ... - - -def root_validator( - _func: Optional[AnyCallable] = None, *, pre: bool = False, allow_reuse: bool = False, skip_on_failure: bool = False -) -> Union[classmethod, Callable[[AnyCallable], classmethod]]: - """ - Decorate methods on a model indicating that they should be used to validate (and perhaps modify) data either - before or after standard model parsing/validation is performed. - """ - if _func: - f_cls = _prepare_validator(_func, allow_reuse) - setattr( - f_cls, ROOT_VALIDATOR_CONFIG_KEY, Validator(func=f_cls.__func__, pre=pre, skip_on_failure=skip_on_failure) - ) - return f_cls - - def dec(f: AnyCallable) -> classmethod: - f_cls = _prepare_validator(f, allow_reuse) - setattr( - f_cls, ROOT_VALIDATOR_CONFIG_KEY, Validator(func=f_cls.__func__, pre=pre, skip_on_failure=skip_on_failure) - ) - return f_cls - - return dec - - -def _prepare_validator(function: AnyCallable, allow_reuse: bool) -> classmethod: - """ - Avoid validators with duplicated names since without this, validators can be overwritten silently - which generally isn't the intended behaviour, don't run in ipython (see #312) or if allow_reuse is False. - """ - f_cls = function if isinstance(function, classmethod) else classmethod(function) - if not in_ipython() and not allow_reuse: - ref = f_cls.__func__.__module__ + '.' + f_cls.__func__.__qualname__ - if ref in _FUNCS: - raise ConfigError(f'duplicate validator function "{ref}"; if this is intended, set `allow_reuse=True`') - _FUNCS.add(ref) - return f_cls - - -class ValidatorGroup: - def __init__(self, validators: 'ValidatorListDict') -> None: - self.validators = validators - self.used_validators = {'*'} - - def get_validators(self, name: str) -> Optional[Dict[str, Validator]]: - self.used_validators.add(name) - validators = self.validators.get(name, []) - if name != ROOT_KEY: - validators += self.validators.get('*', []) - if validators: - return {v.func.__name__: v for v in validators} - else: - return None - - def check_for_unused(self) -> None: - unused_validators = set( - chain.from_iterable( - (v.func.__name__ for v in self.validators[f] if v.check_fields) - for f in (self.validators.keys() - self.used_validators) - ) - ) - if unused_validators: - fn = ', '.join(unused_validators) - raise ConfigError( - f"Validators defined with incorrect fields: {fn} " # noqa: Q000 - f"(use check_fields=False if you're inheriting from the model and intended this)" - ) - - -def extract_validators(namespace: Dict[str, Any]) -> Dict[str, List[Validator]]: - validators: Dict[str, List[Validator]] = {} - for var_name, value in namespace.items(): - validator_config = getattr(value, VALIDATOR_CONFIG_KEY, None) - if validator_config: - fields, v = validator_config - for field in fields: - if field in validators: - validators[field].append(v) - else: - validators[field] = [v] - return validators - - -def extract_root_validators(namespace: Dict[str, Any]) -> Tuple[List[AnyCallable], List[Tuple[bool, AnyCallable]]]: - from inspect import signature - - pre_validators: List[AnyCallable] = [] - post_validators: List[Tuple[bool, AnyCallable]] = [] - for name, value in namespace.items(): - validator_config: Optional[Validator] = getattr(value, ROOT_VALIDATOR_CONFIG_KEY, None) - if validator_config: - sig = signature(validator_config.func) - args = list(sig.parameters.keys()) - if args[0] == 'self': - raise ConfigError( - f'Invalid signature for root validator {name}: {sig}, "self" not permitted as first argument, ' - f'should be: (cls, values).' - ) - if len(args) != 2: - raise ConfigError(f'Invalid signature for root validator {name}: {sig}, should be: (cls, values).') - # check function signature - if validator_config.pre: - pre_validators.append(validator_config.func) - else: - post_validators.append((validator_config.skip_on_failure, validator_config.func)) - return pre_validators, post_validators - - -def inherit_validators(base_validators: 'ValidatorListDict', validators: 'ValidatorListDict') -> 'ValidatorListDict': - for field, field_validators in base_validators.items(): - if field not in validators: - validators[field] = [] - validators[field] += field_validators - return validators - - -def make_generic_validator(validator: AnyCallable) -> 'ValidatorCallable': - """ - Make a generic function which calls a validator with the right arguments. - - Unfortunately other approaches (eg. return a partial of a function that builds the arguments) is slow, - hence this laborious way of doing things. - - It's done like this so validators don't all need **kwargs in their signature, eg. any combination of - the arguments "values", "fields" and/or "config" are permitted. - """ - from inspect import signature - - sig = signature(validator) - args = list(sig.parameters.keys()) - first_arg = args.pop(0) - if first_arg == 'self': - raise ConfigError( - f'Invalid signature for validator {validator}: {sig}, "self" not permitted as first argument, ' - f'should be: (cls, value, values, config, field), "values", "config" and "field" are all optional.' - ) - elif first_arg == 'cls': - # assume the second argument is value - return wraps(validator)(_generic_validator_cls(validator, sig, set(args[1:]))) - else: - # assume the first argument was value which has already been removed - return wraps(validator)(_generic_validator_basic(validator, sig, set(args))) - - -def prep_validators(v_funcs: Iterable[AnyCallable]) -> 'ValidatorsList': - return [make_generic_validator(f) for f in v_funcs if f] - - -all_kwargs = {'values', 'field', 'config'} - - -def _generic_validator_cls(validator: AnyCallable, sig: 'Signature', args: Set[str]) -> 'ValidatorCallable': - # assume the first argument is value - has_kwargs = False - if 'kwargs' in args: - has_kwargs = True - args -= {'kwargs'} - - if not args.issubset(all_kwargs): - raise ConfigError( - f'Invalid signature for validator {validator}: {sig}, should be: ' - f'(cls, value, values, config, field), "values", "config" and "field" are all optional.' - ) - - if has_kwargs: - return lambda cls, v, values, field, config: validator(cls, v, values=values, field=field, config=config) - elif args == set(): - return lambda cls, v, values, field, config: validator(cls, v) - elif args == {'values'}: - return lambda cls, v, values, field, config: validator(cls, v, values=values) - elif args == {'field'}: - return lambda cls, v, values, field, config: validator(cls, v, field=field) - elif args == {'config'}: - return lambda cls, v, values, field, config: validator(cls, v, config=config) - elif args == {'values', 'field'}: - return lambda cls, v, values, field, config: validator(cls, v, values=values, field=field) - elif args == {'values', 'config'}: - return lambda cls, v, values, field, config: validator(cls, v, values=values, config=config) - elif args == {'field', 'config'}: - return lambda cls, v, values, field, config: validator(cls, v, field=field, config=config) - else: - # args == {'values', 'field', 'config'} - return lambda cls, v, values, field, config: validator(cls, v, values=values, field=field, config=config) - - -def _generic_validator_basic(validator: AnyCallable, sig: 'Signature', args: Set[str]) -> 'ValidatorCallable': - has_kwargs = False - if 'kwargs' in args: - has_kwargs = True - args -= {'kwargs'} - - if not args.issubset(all_kwargs): - raise ConfigError( - f'Invalid signature for validator {validator}: {sig}, should be: ' - f'(value, values, config, field), "values", "config" and "field" are all optional.' - ) - - if has_kwargs: - return lambda cls, v, values, field, config: validator(v, values=values, field=field, config=config) - elif args == set(): - return lambda cls, v, values, field, config: validator(v) - elif args == {'values'}: - return lambda cls, v, values, field, config: validator(v, values=values) - elif args == {'field'}: - return lambda cls, v, values, field, config: validator(v, field=field) - elif args == {'config'}: - return lambda cls, v, values, field, config: validator(v, config=config) - elif args == {'values', 'field'}: - return lambda cls, v, values, field, config: validator(v, values=values, field=field) - elif args == {'values', 'config'}: - return lambda cls, v, values, field, config: validator(v, values=values, config=config) - elif args == {'field', 'config'}: - return lambda cls, v, values, field, config: validator(v, field=field, config=config) - else: - # args == {'values', 'field', 'config'} - return lambda cls, v, values, field, config: validator(v, values=values, field=field, config=config) - - -def gather_all_validators(type_: 'ModelOrDc') -> Dict[str, classmethod]: - all_attributes = ChainMap(*[cls.__dict__ for cls in type_.__mro__]) - return { - k: v - for k, v in all_attributes.items() - if hasattr(v, VALIDATOR_CONFIG_KEY) or hasattr(v, ROOT_VALIDATOR_CONFIG_KEY) - } diff --git a/env/lib/python3.8/site-packages/pydantic/color.py b/env/lib/python3.8/site-packages/pydantic/color.py deleted file mode 100644 index 97fc76bf..00000000 --- a/env/lib/python3.8/site-packages/pydantic/color.py +++ /dev/null @@ -1,488 +0,0 @@ -""" -Color definitions are used as per CSS3 specification: -http://www.w3.org/TR/css3-color/#svg-color - -A few colors have multiple names referring to the sames colors, eg. `grey` and `gray` or `aqua` and `cyan`. - -In these cases the LAST color when sorted alphabetically takes preferences, -eg. Color((0, 255, 255)).as_named() == 'cyan' because "cyan" comes after "aqua". -""" -import math -import re -from colorsys import hls_to_rgb, rgb_to_hls -from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union, cast - -from .errors import ColorError -from .utils import Representation, almost_equal_floats - -if TYPE_CHECKING: - from .typing import CallableGenerator, ReprArgs - -ColorTuple = Union[Tuple[int, int, int], Tuple[int, int, int, float]] -ColorType = Union[ColorTuple, str] -HslColorTuple = Union[Tuple[float, float, float], Tuple[float, float, float, float]] - - -class RGBA: - """ - Internal use only as a representation of a color. - """ - - __slots__ = 'r', 'g', 'b', 'alpha', '_tuple' - - def __init__(self, r: float, g: float, b: float, alpha: Optional[float]): - self.r = r - self.g = g - self.b = b - self.alpha = alpha - - self._tuple: Tuple[float, float, float, Optional[float]] = (r, g, b, alpha) - - def __getitem__(self, item: Any) -> Any: - return self._tuple[item] - - -# these are not compiled here to avoid import slowdown, they'll be compiled the first time they're used, then cached -r_hex_short = r'\s*(?:#|0x)?([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?\s*' -r_hex_long = r'\s*(?:#|0x)?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?\s*' -_r_255 = r'(\d{1,3}(?:\.\d+)?)' -_r_comma = r'\s*,\s*' -r_rgb = fr'\s*rgb\(\s*{_r_255}{_r_comma}{_r_255}{_r_comma}{_r_255}\)\s*' -_r_alpha = r'(\d(?:\.\d+)?|\.\d+|\d{1,2}%)' -r_rgba = fr'\s*rgba\(\s*{_r_255}{_r_comma}{_r_255}{_r_comma}{_r_255}{_r_comma}{_r_alpha}\s*\)\s*' -_r_h = r'(-?\d+(?:\.\d+)?|-?\.\d+)(deg|rad|turn)?' -_r_sl = r'(\d{1,3}(?:\.\d+)?)%' -r_hsl = fr'\s*hsl\(\s*{_r_h}{_r_comma}{_r_sl}{_r_comma}{_r_sl}\s*\)\s*' -r_hsla = fr'\s*hsl\(\s*{_r_h}{_r_comma}{_r_sl}{_r_comma}{_r_sl}{_r_comma}{_r_alpha}\s*\)\s*' - -# colors where the two hex characters are the same, if all colors match this the short version of hex colors can be used -repeat_colors = {int(c * 2, 16) for c in '0123456789abcdef'} -rads = 2 * math.pi - - -class Color(Representation): - __slots__ = '_original', '_rgba' - - def __init__(self, value: ColorType) -> None: - self._rgba: RGBA - self._original: ColorType - if isinstance(value, (tuple, list)): - self._rgba = parse_tuple(value) - elif isinstance(value, str): - self._rgba = parse_str(value) - elif isinstance(value, Color): - self._rgba = value._rgba - value = value._original - else: - raise ColorError(reason='value must be a tuple, list or string') - - # if we've got here value must be a valid color - self._original = value - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='color') - - def original(self) -> ColorType: - """ - Original value passed to Color - """ - return self._original - - def as_named(self, *, fallback: bool = False) -> str: - if self._rgba.alpha is None: - rgb = cast(Tuple[int, int, int], self.as_rgb_tuple()) - try: - return COLORS_BY_VALUE[rgb] - except KeyError as e: - if fallback: - return self.as_hex() - else: - raise ValueError('no named color found, use fallback=True, as_hex() or as_rgb()') from e - else: - return self.as_hex() - - def as_hex(self) -> str: - """ - Hex string representing the color can be 3, 4, 6 or 8 characters depending on whether the string - a "short" representation of the color is possible and whether there's an alpha channel. - """ - values = [float_to_255(c) for c in self._rgba[:3]] - if self._rgba.alpha is not None: - values.append(float_to_255(self._rgba.alpha)) - - as_hex = ''.join(f'{v:02x}' for v in values) - if all(c in repeat_colors for c in values): - as_hex = ''.join(as_hex[c] for c in range(0, len(as_hex), 2)) - return '#' + as_hex - - def as_rgb(self) -> str: - """ - Color as an rgb(, , ) or rgba(, , , ) string. - """ - if self._rgba.alpha is None: - return f'rgb({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)})' - else: - return ( - f'rgba({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)}, ' - f'{round(self._alpha_float(), 2)})' - ) - - def as_rgb_tuple(self, *, alpha: Optional[bool] = None) -> ColorTuple: - """ - Color as an RGB or RGBA tuple; red, green and blue are in the range 0 to 255, alpha if included is - in the range 0 to 1. - - :param alpha: whether to include the alpha channel, options are - None - (default) include alpha only if it's set (e.g. not None) - True - always include alpha, - False - always omit alpha, - """ - r, g, b = [float_to_255(c) for c in self._rgba[:3]] - if alpha is None: - if self._rgba.alpha is None: - return r, g, b - else: - return r, g, b, self._alpha_float() - elif alpha: - return r, g, b, self._alpha_float() - else: - # alpha is False - return r, g, b - - def as_hsl(self) -> str: - """ - Color as an hsl(, , ) or hsl(, , , ) string. - """ - if self._rgba.alpha is None: - h, s, li = self.as_hsl_tuple(alpha=False) # type: ignore - return f'hsl({h * 360:0.0f}, {s * 100:0.0f}%, {li * 100:0.0f}%)' - else: - h, s, li, a = self.as_hsl_tuple(alpha=True) # type: ignore - return f'hsl({h * 360:0.0f}, {s * 100:0.0f}%, {li * 100:0.0f}%, {round(a, 2)})' - - def as_hsl_tuple(self, *, alpha: Optional[bool] = None) -> HslColorTuple: - """ - Color as an HSL or HSLA tuple, e.g. hue, saturation, lightness and optionally alpha; all elements are in - the range 0 to 1. - - NOTE: this is HSL as used in HTML and most other places, not HLS as used in python's colorsys. - - :param alpha: whether to include the alpha channel, options are - None - (default) include alpha only if it's set (e.g. not None) - True - always include alpha, - False - always omit alpha, - """ - h, l, s = rgb_to_hls(self._rgba.r, self._rgba.g, self._rgba.b) - if alpha is None: - if self._rgba.alpha is None: - return h, s, l - else: - return h, s, l, self._alpha_float() - if alpha: - return h, s, l, self._alpha_float() - else: - # alpha is False - return h, s, l - - def _alpha_float(self) -> float: - return 1 if self._rgba.alpha is None else self._rgba.alpha - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls - - def __str__(self) -> str: - return self.as_named(fallback=True) - - def __repr_args__(self) -> 'ReprArgs': - return [(None, self.as_named(fallback=True))] + [('rgb', self.as_rgb_tuple())] # type: ignore - - -def parse_tuple(value: Tuple[Any, ...]) -> RGBA: - """ - Parse a tuple or list as a color. - """ - if len(value) == 3: - r, g, b = [parse_color_value(v) for v in value] - return RGBA(r, g, b, None) - elif len(value) == 4: - r, g, b = [parse_color_value(v) for v in value[:3]] - return RGBA(r, g, b, parse_float_alpha(value[3])) - else: - raise ColorError(reason='tuples must have length 3 or 4') - - -def parse_str(value: str) -> RGBA: - """ - Parse a string to an RGBA tuple, trying the following formats (in this order): - * named color, see COLORS_BY_NAME below - * hex short eg. `fff` (prefix can be `#`, `0x` or nothing) - * hex long eg. `ffffff` (prefix can be `#`, `0x` or nothing) - * `rgb(, , ) ` - * `rgba(, , , )` - """ - value_lower = value.lower() - try: - r, g, b = COLORS_BY_NAME[value_lower] - except KeyError: - pass - else: - return ints_to_rgba(r, g, b, None) - - m = re.fullmatch(r_hex_short, value_lower) - if m: - *rgb, a = m.groups() - r, g, b = [int(v * 2, 16) for v in rgb] - if a: - alpha: Optional[float] = int(a * 2, 16) / 255 - else: - alpha = None - return ints_to_rgba(r, g, b, alpha) - - m = re.fullmatch(r_hex_long, value_lower) - if m: - *rgb, a = m.groups() - r, g, b = [int(v, 16) for v in rgb] - if a: - alpha = int(a, 16) / 255 - else: - alpha = None - return ints_to_rgba(r, g, b, alpha) - - m = re.fullmatch(r_rgb, value_lower) - if m: - return ints_to_rgba(*m.groups(), None) # type: ignore - - m = re.fullmatch(r_rgba, value_lower) - if m: - return ints_to_rgba(*m.groups()) # type: ignore - - m = re.fullmatch(r_hsl, value_lower) - if m: - h, h_units, s, l_ = m.groups() - return parse_hsl(h, h_units, s, l_) - - m = re.fullmatch(r_hsla, value_lower) - if m: - h, h_units, s, l_, a = m.groups() - return parse_hsl(h, h_units, s, l_, parse_float_alpha(a)) - - raise ColorError(reason='string not recognised as a valid color') - - -def ints_to_rgba(r: Union[int, str], g: Union[int, str], b: Union[int, str], alpha: Optional[float]) -> RGBA: - return RGBA(parse_color_value(r), parse_color_value(g), parse_color_value(b), parse_float_alpha(alpha)) - - -def parse_color_value(value: Union[int, str], max_val: int = 255) -> float: - """ - Parse a value checking it's a valid int in the range 0 to max_val and divide by max_val to give a number - in the range 0 to 1 - """ - try: - color = float(value) - except ValueError: - raise ColorError(reason='color values must be a valid number') - if 0 <= color <= max_val: - return color / max_val - else: - raise ColorError(reason=f'color values must be in the range 0 to {max_val}') - - -def parse_float_alpha(value: Union[None, str, float, int]) -> Optional[float]: - """ - Parse a value checking it's a valid float in the range 0 to 1 - """ - if value is None: - return None - try: - if isinstance(value, str) and value.endswith('%'): - alpha = float(value[:-1]) / 100 - else: - alpha = float(value) - except ValueError: - raise ColorError(reason='alpha values must be a valid float') - - if almost_equal_floats(alpha, 1): - return None - elif 0 <= alpha <= 1: - return alpha - else: - raise ColorError(reason='alpha values must be in the range 0 to 1') - - -def parse_hsl(h: str, h_units: str, sat: str, light: str, alpha: Optional[float] = None) -> RGBA: - """ - Parse raw hue, saturation, lightness and alpha values and convert to RGBA. - """ - s_value, l_value = parse_color_value(sat, 100), parse_color_value(light, 100) - - h_value = float(h) - if h_units in {None, 'deg'}: - h_value = h_value % 360 / 360 - elif h_units == 'rad': - h_value = h_value % rads / rads - else: - # turns - h_value = h_value % 1 - - r, g, b = hls_to_rgb(h_value, l_value, s_value) - return RGBA(r, g, b, alpha) - - -def float_to_255(c: float) -> int: - return int(round(c * 255)) - - -COLORS_BY_NAME = { - 'aliceblue': (240, 248, 255), - 'antiquewhite': (250, 235, 215), - 'aqua': (0, 255, 255), - 'aquamarine': (127, 255, 212), - 'azure': (240, 255, 255), - 'beige': (245, 245, 220), - 'bisque': (255, 228, 196), - 'black': (0, 0, 0), - 'blanchedalmond': (255, 235, 205), - 'blue': (0, 0, 255), - 'blueviolet': (138, 43, 226), - 'brown': (165, 42, 42), - 'burlywood': (222, 184, 135), - 'cadetblue': (95, 158, 160), - 'chartreuse': (127, 255, 0), - 'chocolate': (210, 105, 30), - 'coral': (255, 127, 80), - 'cornflowerblue': (100, 149, 237), - 'cornsilk': (255, 248, 220), - 'crimson': (220, 20, 60), - 'cyan': (0, 255, 255), - 'darkblue': (0, 0, 139), - 'darkcyan': (0, 139, 139), - 'darkgoldenrod': (184, 134, 11), - 'darkgray': (169, 169, 169), - 'darkgreen': (0, 100, 0), - 'darkgrey': (169, 169, 169), - 'darkkhaki': (189, 183, 107), - 'darkmagenta': (139, 0, 139), - 'darkolivegreen': (85, 107, 47), - 'darkorange': (255, 140, 0), - 'darkorchid': (153, 50, 204), - 'darkred': (139, 0, 0), - 'darksalmon': (233, 150, 122), - 'darkseagreen': (143, 188, 143), - 'darkslateblue': (72, 61, 139), - 'darkslategray': (47, 79, 79), - 'darkslategrey': (47, 79, 79), - 'darkturquoise': (0, 206, 209), - 'darkviolet': (148, 0, 211), - 'deeppink': (255, 20, 147), - 'deepskyblue': (0, 191, 255), - 'dimgray': (105, 105, 105), - 'dimgrey': (105, 105, 105), - 'dodgerblue': (30, 144, 255), - 'firebrick': (178, 34, 34), - 'floralwhite': (255, 250, 240), - 'forestgreen': (34, 139, 34), - 'fuchsia': (255, 0, 255), - 'gainsboro': (220, 220, 220), - 'ghostwhite': (248, 248, 255), - 'gold': (255, 215, 0), - 'goldenrod': (218, 165, 32), - 'gray': (128, 128, 128), - 'green': (0, 128, 0), - 'greenyellow': (173, 255, 47), - 'grey': (128, 128, 128), - 'honeydew': (240, 255, 240), - 'hotpink': (255, 105, 180), - 'indianred': (205, 92, 92), - 'indigo': (75, 0, 130), - 'ivory': (255, 255, 240), - 'khaki': (240, 230, 140), - 'lavender': (230, 230, 250), - 'lavenderblush': (255, 240, 245), - 'lawngreen': (124, 252, 0), - 'lemonchiffon': (255, 250, 205), - 'lightblue': (173, 216, 230), - 'lightcoral': (240, 128, 128), - 'lightcyan': (224, 255, 255), - 'lightgoldenrodyellow': (250, 250, 210), - 'lightgray': (211, 211, 211), - 'lightgreen': (144, 238, 144), - 'lightgrey': (211, 211, 211), - 'lightpink': (255, 182, 193), - 'lightsalmon': (255, 160, 122), - 'lightseagreen': (32, 178, 170), - 'lightskyblue': (135, 206, 250), - 'lightslategray': (119, 136, 153), - 'lightslategrey': (119, 136, 153), - 'lightsteelblue': (176, 196, 222), - 'lightyellow': (255, 255, 224), - 'lime': (0, 255, 0), - 'limegreen': (50, 205, 50), - 'linen': (250, 240, 230), - 'magenta': (255, 0, 255), - 'maroon': (128, 0, 0), - 'mediumaquamarine': (102, 205, 170), - 'mediumblue': (0, 0, 205), - 'mediumorchid': (186, 85, 211), - 'mediumpurple': (147, 112, 219), - 'mediumseagreen': (60, 179, 113), - 'mediumslateblue': (123, 104, 238), - 'mediumspringgreen': (0, 250, 154), - 'mediumturquoise': (72, 209, 204), - 'mediumvioletred': (199, 21, 133), - 'midnightblue': (25, 25, 112), - 'mintcream': (245, 255, 250), - 'mistyrose': (255, 228, 225), - 'moccasin': (255, 228, 181), - 'navajowhite': (255, 222, 173), - 'navy': (0, 0, 128), - 'oldlace': (253, 245, 230), - 'olive': (128, 128, 0), - 'olivedrab': (107, 142, 35), - 'orange': (255, 165, 0), - 'orangered': (255, 69, 0), - 'orchid': (218, 112, 214), - 'palegoldenrod': (238, 232, 170), - 'palegreen': (152, 251, 152), - 'paleturquoise': (175, 238, 238), - 'palevioletred': (219, 112, 147), - 'papayawhip': (255, 239, 213), - 'peachpuff': (255, 218, 185), - 'peru': (205, 133, 63), - 'pink': (255, 192, 203), - 'plum': (221, 160, 221), - 'powderblue': (176, 224, 230), - 'purple': (128, 0, 128), - 'red': (255, 0, 0), - 'rosybrown': (188, 143, 143), - 'royalblue': (65, 105, 225), - 'saddlebrown': (139, 69, 19), - 'salmon': (250, 128, 114), - 'sandybrown': (244, 164, 96), - 'seagreen': (46, 139, 87), - 'seashell': (255, 245, 238), - 'sienna': (160, 82, 45), - 'silver': (192, 192, 192), - 'skyblue': (135, 206, 235), - 'slateblue': (106, 90, 205), - 'slategray': (112, 128, 144), - 'slategrey': (112, 128, 144), - 'snow': (255, 250, 250), - 'springgreen': (0, 255, 127), - 'steelblue': (70, 130, 180), - 'tan': (210, 180, 140), - 'teal': (0, 128, 128), - 'thistle': (216, 191, 216), - 'tomato': (255, 99, 71), - 'turquoise': (64, 224, 208), - 'violet': (238, 130, 238), - 'wheat': (245, 222, 179), - 'white': (255, 255, 255), - 'whitesmoke': (245, 245, 245), - 'yellow': (255, 255, 0), - 'yellowgreen': (154, 205, 50), -} - -COLORS_BY_VALUE = {v: k for k, v in COLORS_BY_NAME.items()} diff --git a/env/lib/python3.8/site-packages/pydantic/dataclasses.py b/env/lib/python3.8/site-packages/pydantic/dataclasses.py deleted file mode 100644 index 0d28e1b2..00000000 --- a/env/lib/python3.8/site-packages/pydantic/dataclasses.py +++ /dev/null @@ -1,228 +0,0 @@ -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Type, TypeVar, Union, overload - -from .class_validators import gather_all_validators -from .error_wrappers import ValidationError -from .errors import DataclassTypeError -from .fields import Required -from .main import create_model, validate_model -from .utils import ClassAttribute - -if TYPE_CHECKING: - from .main import BaseConfig, BaseModel # noqa: F401 - from .typing import CallableGenerator - - DataclassT = TypeVar('DataclassT', bound='Dataclass') - - class Dataclass: - __pydantic_model__: Type[BaseModel] - __initialised__: bool - __post_init_original__: Optional[Callable[..., None]] - __processed__: Optional[ClassAttribute] - - def __init__(self, *args: Any, **kwargs: Any) -> None: - pass - - @classmethod - def __get_validators__(cls: Type['Dataclass']) -> 'CallableGenerator': - pass - - @classmethod - def __validate__(cls: Type['DataclassT'], v: Any) -> 'DataclassT': - pass - - def __call__(self: 'DataclassT', *args: Any, **kwargs: Any) -> 'DataclassT': - pass - - -def _validate_dataclass(cls: Type['DataclassT'], v: Any) -> 'DataclassT': - if isinstance(v, cls): - return v - elif isinstance(v, (list, tuple)): - return cls(*v) - elif isinstance(v, dict): - return cls(**v) - # In nested dataclasses, v can be of type `dataclasses.dataclass`. - # But to validate fields `cls` will be in fact a `pydantic.dataclasses.dataclass`, - # which inherits directly from the class of `v`. - elif is_builtin_dataclass(v) and cls.__bases__[0] is type(v): - import dataclasses - - return cls(**dataclasses.asdict(v)) - else: - raise DataclassTypeError(class_name=cls.__name__) - - -def _get_validators(cls: Type['Dataclass']) -> 'CallableGenerator': - yield cls.__validate__ - - -def setattr_validate_assignment(self: 'Dataclass', name: str, value: Any) -> None: - if self.__initialised__: - d = dict(self.__dict__) - d.pop(name, None) - known_field = self.__pydantic_model__.__fields__.get(name, None) - if known_field: - value, error_ = known_field.validate(value, d, loc=name, cls=self.__class__) - if error_: - raise ValidationError([error_], self.__class__) - - object.__setattr__(self, name, value) - - -def is_builtin_dataclass(_cls: Type[Any]) -> bool: - """ - `dataclasses.is_dataclass` is True if one of the class parents is a `dataclass`. - This is why we also add a class attribute `__processed__` to only consider 'direct' built-in dataclasses - """ - import dataclasses - - return not hasattr(_cls, '__processed__') and dataclasses.is_dataclass(_cls) - - -def _process_class( - _cls: Type[Any], - init: bool, - repr: bool, - eq: bool, - order: bool, - unsafe_hash: bool, - frozen: bool, - config: Optional[Type[Any]], -) -> Type['Dataclass']: - import dataclasses - - post_init_original = getattr(_cls, '__post_init__', None) - if post_init_original and post_init_original.__name__ == '_pydantic_post_init': - post_init_original = None - if not post_init_original: - post_init_original = getattr(_cls, '__post_init_original__', None) - - post_init_post_parse = getattr(_cls, '__post_init_post_parse__', None) - - def _pydantic_post_init(self: 'Dataclass', *initvars: Any) -> None: - if post_init_original is not None: - post_init_original(self, *initvars) - d, _, validation_error = validate_model(self.__pydantic_model__, self.__dict__, cls=self.__class__) - if validation_error: - raise validation_error - object.__setattr__(self, '__dict__', d) - object.__setattr__(self, '__initialised__', True) - if post_init_post_parse is not None: - post_init_post_parse(self, *initvars) - - # If the class is already a dataclass, __post_init__ will not be called automatically - # so no validation will be added. - # We hence create dynamically a new dataclass: - # ``` - # @dataclasses.dataclass - # class NewClass(_cls): - # __post_init__ = _pydantic_post_init - # ``` - # with the exact same fields as the base dataclass - if is_builtin_dataclass(_cls): - _cls = type( - _cls.__name__, (_cls,), {'__annotations__': _cls.__annotations__, '__post_init__': _pydantic_post_init} - ) - else: - _cls.__post_init__ = _pydantic_post_init - cls: Type['Dataclass'] = dataclasses.dataclass( # type: ignore - _cls, init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen - ) - cls.__processed__ = ClassAttribute('__processed__', True) - - fields: Dict[str, Any] = {} - for field in dataclasses.fields(cls): - - if field.default != dataclasses.MISSING: - field_value = field.default - # mypy issue 7020 and 708 - elif field.default_factory != dataclasses.MISSING: # type: ignore - field_value = field.default_factory() # type: ignore - else: - field_value = Required - - fields[field.name] = (field.type, field_value) - - validators = gather_all_validators(cls) - cls.__pydantic_model__ = create_model( - cls.__name__, __config__=config, __module__=_cls.__module__, __validators__=validators, **fields - ) - - cls.__initialised__ = False - cls.__validate__ = classmethod(_validate_dataclass) # type: ignore[assignment] - cls.__get_validators__ = classmethod(_get_validators) # type: ignore[assignment] - if post_init_original: - cls.__post_init_original__ = post_init_original - - if cls.__pydantic_model__.__config__.validate_assignment and not frozen: - cls.__setattr__ = setattr_validate_assignment # type: ignore[assignment] - - return cls - - -@overload -def dataclass( - *, - init: bool = True, - repr: bool = True, - eq: bool = True, - order: bool = False, - unsafe_hash: bool = False, - frozen: bool = False, - config: Type[Any] = None, -) -> Callable[[Type[Any]], Type['Dataclass']]: - ... - - -@overload -def dataclass( - _cls: Type[Any], - *, - init: bool = True, - repr: bool = True, - eq: bool = True, - order: bool = False, - unsafe_hash: bool = False, - frozen: bool = False, - config: Type[Any] = None, -) -> Type['Dataclass']: - ... - - -def dataclass( - _cls: Optional[Type[Any]] = None, - *, - init: bool = True, - repr: bool = True, - eq: bool = True, - order: bool = False, - unsafe_hash: bool = False, - frozen: bool = False, - config: Type[Any] = None, -) -> Union[Callable[[Type[Any]], Type['Dataclass']], Type['Dataclass']]: - """ - Like the python standard lib dataclasses but with type validation. - - Arguments are the same as for standard dataclasses, except for validate_assignment which has the same meaning - as Config.validate_assignment. - """ - - def wrap(cls: Type[Any]) -> Type['Dataclass']: - return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, config) - - if _cls is None: - return wrap - - return wrap(_cls) - - -def make_dataclass_validator(_cls: Type[Any], config: Type['BaseConfig']) -> 'CallableGenerator': - """ - Create a pydantic.dataclass from a builtin dataclass to add type validation - and yield the validators - It retrieves the parameters of the dataclass and forwards them to the newly created dataclass - """ - dataclass_params = _cls.__dataclass_params__ - stdlib_dataclass_parameters = {param: getattr(dataclass_params, param) for param in dataclass_params.__slots__} - cls = dataclass(_cls, config=config, **stdlib_dataclass_parameters) - yield from _get_validators(cls) diff --git a/env/lib/python3.8/site-packages/pydantic/datetime_parse.py b/env/lib/python3.8/site-packages/pydantic/datetime_parse.py deleted file mode 100644 index d567c5c5..00000000 --- a/env/lib/python3.8/site-packages/pydantic/datetime_parse.py +++ /dev/null @@ -1,241 +0,0 @@ -""" -Functions to parse datetime objects. - -We're using regular expressions rather than time.strptime because: -- They provide both validation and parsing. -- They're more flexible for datetimes. -- The date/datetime/time constructors produce friendlier error messages. - -Stolen from https://raw.githubusercontent.com/django/django/master/django/utils/dateparse.py at -9718fa2e8abe430c3526a9278dd976443d4ae3c6 - -Changed to: -* use standard python datetime types not django.utils.timezone -* raise ValueError when regex doesn't match rather than returning None -* support parsing unix timestamps for dates and datetimes -""" -import re -from datetime import date, datetime, time, timedelta, timezone -from typing import Dict, Optional, Type, Union - -from . import errors - -date_expr = r'(?P\d{4})-(?P\d{1,2})-(?P\d{1,2})' -time_expr = ( - r'(?P\d{1,2}):(?P\d{1,2})' - r'(?::(?P\d{1,2})(?:\.(?P\d{1,6})\d{0,6})?)?' - r'(?PZ|[+-]\d{2}(?::?\d{2})?)?$' -) - -date_re = re.compile(f'{date_expr}$') -time_re = re.compile(time_expr) -datetime_re = re.compile(f'{date_expr}[T ]{time_expr}') - -standard_duration_re = re.compile( - r'^' - r'(?:(?P-?\d+) (days?, )?)?' - r'((?:(?P-?\d+):)(?=\d+:\d+))?' - r'(?:(?P-?\d+):)?' - r'(?P-?\d+)' - r'(?:\.(?P\d{1,6})\d{0,6})?' - r'$' -) - -# Support the sections of ISO 8601 date representation that are accepted by timedelta -iso8601_duration_re = re.compile( - r'^(?P[-+]?)' - r'P' - r'(?:(?P\d+(.\d+)?)D)?' - r'(?:T' - r'(?:(?P\d+(.\d+)?)H)?' - r'(?:(?P\d+(.\d+)?)M)?' - r'(?:(?P\d+(.\d+)?)S)?' - r')?' - r'$' -) - -EPOCH = datetime(1970, 1, 1) -# if greater than this, the number is in ms, if less than or equal it's in seconds -# (in seconds this is 11th October 2603, in ms it's 20th August 1970) -MS_WATERSHED = int(2e10) -StrBytesIntFloat = Union[str, bytes, int, float] - - -def get_numeric(value: StrBytesIntFloat, native_expected_type: str) -> Union[None, int, float]: - if isinstance(value, (int, float)): - return value - try: - return float(value) - except ValueError: - return None - except TypeError: - raise TypeError(f'invalid type; expected {native_expected_type}, string, bytes, int or float') - - -def from_unix_seconds(seconds: Union[int, float]) -> datetime: - while abs(seconds) > MS_WATERSHED: - seconds /= 1000 - dt = EPOCH + timedelta(seconds=seconds) - return dt.replace(tzinfo=timezone.utc) - - -def _parse_timezone(value: Optional[str], error: Type[Exception]) -> Union[None, int, timezone]: - if value == 'Z': - return timezone.utc - elif value is not None: - offset_mins = int(value[-2:]) if len(value) > 3 else 0 - offset = 60 * int(value[1:3]) + offset_mins - if value[0] == '-': - offset = -offset - try: - return timezone(timedelta(minutes=offset)) - except ValueError: - raise error() - else: - return None - - -def parse_date(value: Union[date, StrBytesIntFloat]) -> date: - """ - Parse a date/int/float/string and return a datetime.date. - - Raise ValueError if the input is well formatted but not a valid date. - Raise ValueError if the input isn't well formatted. - """ - if isinstance(value, date): - if isinstance(value, datetime): - return value.date() - else: - return value - - number = get_numeric(value, 'date') - if number is not None: - return from_unix_seconds(number).date() - - if isinstance(value, bytes): - value = value.decode() - - match = date_re.match(value) # type: ignore - if match is None: - raise errors.DateError() - - kw = {k: int(v) for k, v in match.groupdict().items()} - - try: - return date(**kw) - except ValueError: - raise errors.DateError() - - -def parse_time(value: Union[time, StrBytesIntFloat]) -> time: - """ - Parse a time/string and return a datetime.time. - - Raise ValueError if the input is well formatted but not a valid time. - Raise ValueError if the input isn't well formatted, in particular if it contains an offset. - """ - if isinstance(value, time): - return value - - number = get_numeric(value, 'time') - if number is not None: - if number >= 86400: - # doesn't make sense since the time time loop back around to 0 - raise errors.TimeError() - return (datetime.min + timedelta(seconds=number)).time() - - if isinstance(value, bytes): - value = value.decode() - - match = time_re.match(value) # type: ignore - if match is None: - raise errors.TimeError() - - kw = match.groupdict() - if kw['microsecond']: - kw['microsecond'] = kw['microsecond'].ljust(6, '0') - - tzinfo = _parse_timezone(kw.pop('tzinfo'), errors.TimeError) - kw_: Dict[str, Union[None, int, timezone]] = {k: int(v) for k, v in kw.items() if v is not None} - kw_['tzinfo'] = tzinfo - - try: - return time(**kw_) # type: ignore - except ValueError: - raise errors.TimeError() - - -def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: - """ - Parse a datetime/int/float/string and return a datetime.datetime. - - This function supports time zone offsets. When the input contains one, - the output uses a timezone with a fixed offset from UTC. - - Raise ValueError if the input is well formatted but not a valid datetime. - Raise ValueError if the input isn't well formatted. - """ - if isinstance(value, datetime): - return value - - number = get_numeric(value, 'datetime') - if number is not None: - return from_unix_seconds(number) - - if isinstance(value, bytes): - value = value.decode() - - match = datetime_re.match(value) # type: ignore - if match is None: - raise errors.DateTimeError() - - kw = match.groupdict() - if kw['microsecond']: - kw['microsecond'] = kw['microsecond'].ljust(6, '0') - - tzinfo = _parse_timezone(kw.pop('tzinfo'), errors.DateTimeError) - kw_: Dict[str, Union[None, int, timezone]] = {k: int(v) for k, v in kw.items() if v is not None} - kw_['tzinfo'] = tzinfo - - try: - return datetime(**kw_) # type: ignore - except ValueError: - raise errors.DateTimeError() - - -def parse_duration(value: StrBytesIntFloat) -> timedelta: - """ - Parse a duration int/float/string and return a datetime.timedelta. - - The preferred format for durations in Django is '%d %H:%M:%S.%f'. - - Also supports ISO 8601 representation. - """ - if isinstance(value, timedelta): - return value - - if isinstance(value, (int, float)): - # bellow code requires a string - value = str(value) - elif isinstance(value, bytes): - value = value.decode() - - try: - match = standard_duration_re.match(value) or iso8601_duration_re.match(value) - except TypeError: - raise TypeError('invalid type; expected timedelta, string, bytes, int or float') - - if not match: - raise errors.DurationError() - - kw = match.groupdict() - sign = -1 if kw.pop('sign', '+') == '-' else 1 - if kw.get('microseconds'): - kw['microseconds'] = kw['microseconds'].ljust(6, '0') - - if kw.get('seconds') and kw.get('microseconds') and kw['seconds'].startswith('-'): - kw['microseconds'] = '-' + kw['microseconds'] - - kw_ = {k: float(v) for k, v in kw.items() if v is not None} - - return sign * timedelta(**kw_) # type: ignore diff --git a/env/lib/python3.8/site-packages/pydantic/decorator.py b/env/lib/python3.8/site-packages/pydantic/decorator.py deleted file mode 100644 index 0d7ca882..00000000 --- a/env/lib/python3.8/site-packages/pydantic/decorator.py +++ /dev/null @@ -1,249 +0,0 @@ -from functools import wraps -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Dict, - List, - Mapping, - Optional, - Tuple, - Type, - TypeVar, - Union, - get_type_hints, - overload, -) - -from . import validator -from .errors import ConfigError -from .main import BaseModel, Extra, create_model -from .utils import to_camel - -__all__ = ('validate_arguments',) - -if TYPE_CHECKING: - from .typing import AnyCallable - - AnyCallableT = TypeVar('AnyCallableT', bound=AnyCallable) - ConfigType = Union[None, Type[Any], Dict[str, Any]] - - -@overload -def validate_arguments(func: None = None, *, config: 'ConfigType' = None) -> Callable[['AnyCallableT'], 'AnyCallableT']: - ... - - -@overload -def validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT': - ... - - -def validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any: - """ - Decorator to validate the arguments passed to a function. - """ - - def validate(_func: 'AnyCallable') -> 'AnyCallable': - vd = ValidatedFunction(_func, config) - - @wraps(_func) - def wrapper_function(*args: Any, **kwargs: Any) -> Any: - return vd.call(*args, **kwargs) - - wrapper_function.vd = vd # type: ignore - wrapper_function.raw_function = vd.raw_function # type: ignore - wrapper_function.model = vd.model # type: ignore - return wrapper_function - - if func: - return validate(func) - else: - return validate - - -ALT_V_ARGS = 'v__args' -ALT_V_KWARGS = 'v__kwargs' -V_POSITIONAL_ONLY_NAME = 'v__positional_only' - - -class ValidatedFunction: - def __init__(self, function: 'AnyCallableT', config: 'ConfigType'): # noqa C901 - from inspect import Parameter, signature - - parameters: Mapping[str, Parameter] = signature(function).parameters - - if parameters.keys() & {ALT_V_ARGS, ALT_V_KWARGS, V_POSITIONAL_ONLY_NAME}: - raise ConfigError( - f'"{ALT_V_ARGS}", "{ALT_V_KWARGS}" and "{V_POSITIONAL_ONLY_NAME}" are not permitted as argument ' - f'names when using the "{validate_arguments.__name__}" decorator' - ) - - self.raw_function = function - self.arg_mapping: Dict[int, str] = {} - self.positional_only_args = set() - self.v_args_name = 'args' - self.v_kwargs_name = 'kwargs' - - type_hints = get_type_hints(function) - takes_args = False - takes_kwargs = False - fields: Dict[str, Tuple[Any, Any]] = {} - for i, (name, p) in enumerate(parameters.items()): - if p.annotation == p.empty: - annotation = Any - else: - annotation = type_hints[name] - - default = ... if p.default == p.empty else p.default - if p.kind == Parameter.POSITIONAL_ONLY: - self.arg_mapping[i] = name - fields[name] = annotation, default - fields[V_POSITIONAL_ONLY_NAME] = List[str], None - self.positional_only_args.add(name) - elif p.kind == Parameter.POSITIONAL_OR_KEYWORD: - self.arg_mapping[i] = name - fields[name] = annotation, default - elif p.kind == Parameter.KEYWORD_ONLY: - fields[name] = annotation, default - elif p.kind == Parameter.VAR_POSITIONAL: - self.v_args_name = name - fields[name] = Tuple[annotation, ...], None - takes_args = True - else: - assert p.kind == Parameter.VAR_KEYWORD, p.kind - self.v_kwargs_name = name - fields[name] = Dict[str, annotation], None # type: ignore - takes_kwargs = True - - # these checks avoid a clash between "args" and a field with that name - if not takes_args and self.v_args_name in fields: - self.v_args_name = ALT_V_ARGS - - # same with "kwargs" - if not takes_kwargs and self.v_kwargs_name in fields: - self.v_kwargs_name = ALT_V_KWARGS - - if not takes_args: - # we add the field so validation below can raise the correct exception - fields[self.v_args_name] = List[Any], None - - if not takes_kwargs: - # same with kwargs - fields[self.v_kwargs_name] = Dict[Any, Any], None - - self.create_model(fields, takes_args, takes_kwargs, config) - - def call(self, *args: Any, **kwargs: Any) -> Any: - values = self.build_values(args, kwargs) - m = self.model(**values) - return self.execute(m) - - def build_values(self, args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Dict[str, Any]: - values: Dict[str, Any] = {} - if args: - arg_iter = enumerate(args) - while True: - try: - i, a = next(arg_iter) - except StopIteration: - break - arg_name = self.arg_mapping.get(i) - if arg_name is not None: - values[arg_name] = a - else: - values[self.v_args_name] = [a] + [a for _, a in arg_iter] - break - - var_kwargs = {} - wrong_positional_args = [] - for k, v in kwargs.items(): - if k in self.model.__fields__: - if k in self.positional_only_args: - wrong_positional_args.append(k) - values[k] = v - else: - var_kwargs[k] = v - - if var_kwargs: - values[self.v_kwargs_name] = var_kwargs - if wrong_positional_args: - values[V_POSITIONAL_ONLY_NAME] = wrong_positional_args - return values - - def execute(self, m: BaseModel) -> Any: - d = {k: v for k, v in m._iter() if k in m.__fields_set__} - kwargs = d.pop(self.v_kwargs_name, None) - if kwargs: - d.update(kwargs) - - if self.v_args_name in d: - args_: List[Any] = [] - in_kwargs = False - kwargs = {} - for name, value in d.items(): - if in_kwargs: - kwargs[name] = value - elif name == self.v_args_name: - args_ += value - in_kwargs = True - else: - args_.append(value) - return self.raw_function(*args_, **kwargs) - elif self.positional_only_args: - args_ = [] - kwargs = {} - for name, value in d.items(): - if name in self.positional_only_args: - args_.append(value) - else: - kwargs[name] = value - return self.raw_function(*args_, **kwargs) - else: - return self.raw_function(**d) - - def create_model(self, fields: Dict[str, Any], takes_args: bool, takes_kwargs: bool, config: 'ConfigType') -> None: - pos_args = len(self.arg_mapping) - - class CustomConfig: - pass - - if not TYPE_CHECKING: # pragma: no branch - if isinstance(config, dict): - CustomConfig = type('Config', (), config) # noqa: F811 - elif config is not None: - CustomConfig = config # noqa: F811 - - if hasattr(CustomConfig, 'fields') or hasattr(CustomConfig, 'alias_generator'): - raise ConfigError( - 'Setting the "fields" and "alias_generator" property on custom Config for ' - '@validate_arguments is not yet supported, please remove.' - ) - - class DecoratorBaseModel(BaseModel): - @validator(self.v_args_name, check_fields=False, allow_reuse=True) - def check_args(cls, v: List[Any]) -> List[Any]: - if takes_args: - return v - - raise TypeError(f'{pos_args} positional arguments expected but {pos_args + len(v)} given') - - @validator(self.v_kwargs_name, check_fields=False, allow_reuse=True) - def check_kwargs(cls, v: Dict[str, Any]) -> Dict[str, Any]: - if takes_kwargs: - return v - - plural = '' if len(v) == 1 else 's' - keys = ', '.join(map(repr, v.keys())) - raise TypeError(f'unexpected keyword argument{plural}: {keys}') - - @validator(V_POSITIONAL_ONLY_NAME, check_fields=False, allow_reuse=True) - def check_positional_only(cls, v: List[str]) -> None: - plural = '' if len(v) == 1 else 's' - keys = ', '.join(map(repr, v)) - raise TypeError(f'positional-only argument{plural} passed as keyword argument{plural}: {keys}') - - class Config(CustomConfig): - extra = Extra.forbid - - self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields) diff --git a/env/lib/python3.8/site-packages/pydantic/env_settings.py b/env/lib/python3.8/site-packages/pydantic/env_settings.py deleted file mode 100644 index 28022d19..00000000 --- a/env/lib/python3.8/site-packages/pydantic/env_settings.py +++ /dev/null @@ -1,175 +0,0 @@ -import os -import warnings -from pathlib import Path -from typing import AbstractSet, Any, Dict, List, Mapping, Optional, Union - -from .fields import ModelField -from .main import BaseConfig, BaseModel, Extra -from .typing import display_as_type -from .utils import deep_update, path_type, sequence_like - -env_file_sentinel = str(object()) - - -class SettingsError(ValueError): - pass - - -class BaseSettings(BaseModel): - """ - Base class for settings, allowing values to be overridden by environment variables. - - This is useful in production for secrets you do not wish to save in code, it plays nicely with docker(-compose), - Heroku and any 12 factor app design. - """ - - def __init__( - __pydantic_self__, - _env_file: Union[Path, str, None] = env_file_sentinel, - _env_file_encoding: Optional[str] = None, - _secrets_dir: Union[Path, str, None] = None, - **values: Any, - ) -> None: - # Uses something other than `self` the first arg to allow "self" as a settable attribute - super().__init__( - **__pydantic_self__._build_values( - values, _env_file=_env_file, _env_file_encoding=_env_file_encoding, _secrets_dir=_secrets_dir - ) - ) - - def _build_values( - self, - init_kwargs: Dict[str, Any], - _env_file: Union[Path, str, None] = None, - _env_file_encoding: Optional[str] = None, - _secrets_dir: Union[Path, str, None] = None, - ) -> Dict[str, Any]: - return deep_update( - self._build_secrets_files(_secrets_dir), self._build_environ(_env_file, _env_file_encoding), init_kwargs - ) - - def _build_secrets_files(self, _secrets_dir: Union[Path, str, None] = None) -> Dict[str, Optional[str]]: - """ - Build fields from "secrets" files. - """ - secrets: Dict[str, Optional[str]] = {} - - secrets_dir = _secrets_dir or self.__config__.secrets_dir - if secrets_dir is None: - return secrets - - secrets_path = Path(secrets_dir).expanduser() - - if not secrets_path.exists(): - raise SettingsError(f'directory "{secrets_path}" does not exist') - if not secrets_path.is_dir(): - raise SettingsError(f'secrets_dir must reference a directory, not a {path_type(secrets_path)}') - - for field in self.__fields__.values(): - for env_name in field.field_info.extra['env_names']: - path = secrets_path / env_name - if path.is_file(): - secrets[field.alias] = path.read_text().strip() - elif path.exists(): - warnings.warn( - f'attempted to load secret file "{path}" but found a {path_type(path)} instead.', - stacklevel=4, - ) - - return secrets - - def _build_environ( - self, _env_file: Union[Path, str, None] = None, _env_file_encoding: Optional[str] = None - ) -> Dict[str, Optional[str]]: - """ - Build environment variables suitable for passing to the Model. - """ - d: Dict[str, Optional[str]] = {} - - if self.__config__.case_sensitive: - env_vars: Mapping[str, Optional[str]] = os.environ - else: - env_vars = {k.lower(): v for k, v in os.environ.items()} - - env_file = _env_file if _env_file != env_file_sentinel else self.__config__.env_file - env_file_encoding = _env_file_encoding if _env_file_encoding is not None else self.__config__.env_file_encoding - if env_file is not None: - env_path = Path(env_file).expanduser() - if env_path.is_file(): - env_vars = { - **read_env_file( - env_path, encoding=env_file_encoding, case_sensitive=self.__config__.case_sensitive - ), - **env_vars, - } - - for field in self.__fields__.values(): - env_val: Optional[str] = None - for env_name in field.field_info.extra['env_names']: - env_val = env_vars.get(env_name) - if env_val is not None: - break - - if env_val is None: - continue - - if field.is_complex(): - try: - env_val = self.__config__.json_loads(env_val) # type: ignore - except ValueError as e: - raise SettingsError(f'error parsing JSON for "{env_name}"') from e - d[field.alias] = env_val - return d - - class Config(BaseConfig): - env_prefix = '' - env_file = None - env_file_encoding = None - secrets_dir = None - validate_all = True - extra = Extra.forbid - arbitrary_types_allowed = True - case_sensitive = False - - @classmethod - def prepare_field(cls, field: ModelField) -> None: - env_names: Union[List[str], AbstractSet[str]] - field_info_from_config = cls.get_field_info(field.name) - - env = field_info_from_config.get('env') or field.field_info.extra.get('env') - if env is None: - if field.has_alias: - warnings.warn( - 'aliases are no longer used by BaseSettings to define which environment variables to read. ' - 'Instead use the "env" field setting. ' - 'See https://pydantic-docs.helpmanual.io/usage/settings/#environment-variable-names', - FutureWarning, - ) - env_names = {cls.env_prefix + field.name} - elif isinstance(env, str): - env_names = {env} - elif isinstance(env, (set, frozenset)): - env_names = env - elif sequence_like(env): - env_names = list(env) - else: - raise TypeError(f'invalid field env: {env!r} ({display_as_type(env)}); should be string, list or set') - - if not cls.case_sensitive: - env_names = env_names.__class__(n.lower() for n in env_names) - field.field_info.extra['env_names'] = env_names - - __config__: Config # type: ignore - - -def read_env_file(file_path: Path, *, encoding: str = None, case_sensitive: bool = False) -> Dict[str, Optional[str]]: - try: - from dotenv import dotenv_values - except ImportError as e: - raise ImportError('python-dotenv is not installed, run `pip install pydantic[dotenv]`') from e - - file_vars: Dict[str, Optional[str]] = dotenv_values(file_path, encoding=encoding or 'utf8') - if not case_sensitive: - return {k.lower(): v for k, v in file_vars.items()} - else: - return file_vars diff --git a/env/lib/python3.8/site-packages/pydantic/error_wrappers.py b/env/lib/python3.8/site-packages/pydantic/error_wrappers.py deleted file mode 100644 index 92d957f8..00000000 --- a/env/lib/python3.8/site-packages/pydantic/error_wrappers.py +++ /dev/null @@ -1,151 +0,0 @@ -import json -from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Sequence, Tuple, Type, Union - -from .json import pydantic_encoder -from .utils import Representation - -if TYPE_CHECKING: - from .main import BaseConfig # noqa: F401 - from .types import ModelOrDc # noqa: F401 - from .typing import ReprArgs - - Loc = Tuple[Union[int, str], ...] - -__all__ = 'ErrorWrapper', 'ValidationError' - - -class ErrorWrapper(Representation): - __slots__ = 'exc', '_loc' - - def __init__(self, exc: Exception, loc: Union[str, 'Loc']) -> None: - self.exc = exc - self._loc = loc - - def loc_tuple(self) -> 'Loc': - if isinstance(self._loc, tuple): - return self._loc - else: - return (self._loc,) - - def __repr_args__(self) -> 'ReprArgs': - return [('exc', self.exc), ('loc', self.loc_tuple())] - - -# ErrorList is something like Union[List[Union[List[ErrorWrapper], ErrorWrapper]], ErrorWrapper] -# but recursive, therefore just use: -ErrorList = Union[Sequence[Any], ErrorWrapper] - - -class ValidationError(Representation, ValueError): - __slots__ = 'raw_errors', 'model', '_error_cache' - - def __init__(self, errors: Sequence[ErrorList], model: 'ModelOrDc') -> None: - self.raw_errors = errors - self.model = model - self._error_cache: Optional[List[Dict[str, Any]]] = None - - def errors(self) -> List[Dict[str, Any]]: - if self._error_cache is None: - try: - config = self.model.__config__ # type: ignore - except AttributeError: - config = self.model.__pydantic_model__.__config__ # type: ignore - self._error_cache = list(flatten_errors(self.raw_errors, config)) - return self._error_cache - - def json(self, *, indent: Union[None, int, str] = 2) -> str: - return json.dumps(self.errors(), indent=indent, default=pydantic_encoder) - - def __str__(self) -> str: - errors = self.errors() - no_errors = len(errors) - return ( - f'{no_errors} validation error{"" if no_errors == 1 else "s"} for {self.model.__name__}\n' - f'{display_errors(errors)}' - ) - - def __repr_args__(self) -> 'ReprArgs': - return [('model', self.model.__name__), ('errors', self.errors())] - - -def display_errors(errors: List[Dict[str, Any]]) -> str: - return '\n'.join(f'{_display_error_loc(e)}\n {e["msg"]} ({_display_error_type_and_ctx(e)})' for e in errors) - - -def _display_error_loc(error: Dict[str, Any]) -> str: - return ' -> '.join(str(e) for e in error['loc']) - - -def _display_error_type_and_ctx(error: Dict[str, Any]) -> str: - t = 'type=' + error['type'] - ctx = error.get('ctx') - if ctx: - return t + ''.join(f'; {k}={v}' for k, v in ctx.items()) - else: - return t - - -def flatten_errors( - errors: Sequence[Any], config: Type['BaseConfig'], loc: Optional['Loc'] = None -) -> Generator[Dict[str, Any], None, None]: - for error in errors: - if isinstance(error, ErrorWrapper): - - if loc: - error_loc = loc + error.loc_tuple() - else: - error_loc = error.loc_tuple() - - if isinstance(error.exc, ValidationError): - yield from flatten_errors(error.exc.raw_errors, config, error_loc) - else: - yield error_dict(error.exc, config, error_loc) - elif isinstance(error, list): - yield from flatten_errors(error, config, loc=loc) - else: - raise RuntimeError(f'Unknown error object: {error}') - - -def error_dict(exc: Exception, config: Type['BaseConfig'], loc: 'Loc') -> Dict[str, Any]: - type_ = get_exc_type(exc.__class__) - msg_template = config.error_msg_templates.get(type_) or getattr(exc, 'msg_template', None) - ctx = exc.__dict__ - if msg_template: - msg = msg_template.format(**ctx) - else: - msg = str(exc) - - d: Dict[str, Any] = {'loc': loc, 'msg': msg, 'type': type_} - - if ctx: - d['ctx'] = ctx - - return d - - -_EXC_TYPE_CACHE: Dict[Type[Exception], str] = {} - - -def get_exc_type(cls: Type[Exception]) -> str: - # slightly more efficient than using lru_cache since we don't need to worry about the cache filling up - try: - return _EXC_TYPE_CACHE[cls] - except KeyError: - r = _get_exc_type(cls) - _EXC_TYPE_CACHE[cls] = r - return r - - -def _get_exc_type(cls: Type[Exception]) -> str: - if issubclass(cls, AssertionError): - return 'assertion_error' - - base_name = 'type_error' if issubclass(cls, TypeError) else 'value_error' - if cls in (TypeError, ValueError): - # just TypeError or ValueError, no extra code - return base_name - - # if it's not a TypeError or ValueError, we just take the lowercase of the exception name - # no chaining or snake case logic, use "code" for more complex error types. - code = getattr(cls, 'code', None) or cls.__name__.replace('Error', '').lower() - return base_name + '.' + code diff --git a/env/lib/python3.8/site-packages/pydantic/errors.py b/env/lib/python3.8/site-packages/pydantic/errors.py deleted file mode 100644 index 4e43a1f0..00000000 --- a/env/lib/python3.8/site-packages/pydantic/errors.py +++ /dev/null @@ -1,577 +0,0 @@ -from decimal import Decimal -from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, Set, Tuple, Type, Union - -from .typing import display_as_type - -if TYPE_CHECKING: - from .typing import DictStrAny - -# explicitly state exports to avoid "from .errors import *" also importing Decimal, Path etc. -__all__ = ( - 'PydanticTypeError', - 'PydanticValueError', - 'ConfigError', - 'MissingError', - 'ExtraError', - 'NoneIsNotAllowedError', - 'NoneIsAllowedError', - 'WrongConstantError', - 'BoolError', - 'BytesError', - 'DictError', - 'EmailError', - 'UrlError', - 'UrlSchemeError', - 'UrlSchemePermittedError', - 'UrlUserInfoError', - 'UrlHostError', - 'UrlHostTldError', - 'UrlPortError', - 'UrlExtraError', - 'EnumError', - 'IntEnumError', - 'EnumMemberError', - 'IntegerError', - 'FloatError', - 'PathError', - '_PathValueError', - 'PathNotExistsError', - 'PathNotAFileError', - 'PathNotADirectoryError', - 'PyObjectError', - 'SequenceError', - 'ListError', - 'SetError', - 'FrozenSetError', - 'TupleError', - 'TupleLengthError', - 'ListMinLengthError', - 'ListMaxLengthError', - 'AnyStrMinLengthError', - 'AnyStrMaxLengthError', - 'StrError', - 'StrRegexError', - '_NumberBoundError', - 'NumberNotGtError', - 'NumberNotGeError', - 'NumberNotLtError', - 'NumberNotLeError', - 'NumberNotMultipleError', - 'DecimalError', - 'DecimalIsNotFiniteError', - 'DecimalMaxDigitsError', - 'DecimalMaxPlacesError', - 'DecimalWholeDigitsError', - 'DateTimeError', - 'DateError', - 'TimeError', - 'DurationError', - 'HashableError', - 'UUIDError', - 'UUIDVersionError', - 'ArbitraryTypeError', - 'ClassError', - 'SubclassError', - 'JsonError', - 'JsonTypeError', - 'PatternError', - 'DataclassTypeError', - 'CallableError', - 'IPvAnyAddressError', - 'IPvAnyInterfaceError', - 'IPvAnyNetworkError', - 'IPv4AddressError', - 'IPv6AddressError', - 'IPv4NetworkError', - 'IPv6NetworkError', - 'IPv4InterfaceError', - 'IPv6InterfaceError', - 'ColorError', - 'StrictBoolError', - 'NotDigitError', - 'LuhnValidationError', - 'InvalidLengthForBrand', - 'InvalidByteSize', - 'InvalidByteSizeUnit', -) - - -def cls_kwargs(cls: Type['PydanticErrorMixin'], ctx: 'DictStrAny') -> 'PydanticErrorMixin': - """ - For built-in exceptions like ValueError or TypeError, we need to implement - __reduce__ to override the default behaviour (instead of __getstate__/__setstate__) - By default pickle protocol 2 calls `cls.__new__(cls, *args)`. - Since we only use kwargs, we need a little constructor to change that. - Note: the callable can't be a lambda as pickle looks in the namespace to find it - """ - return cls(**ctx) - - -class PydanticErrorMixin: - code: str - msg_template: str - - def __init__(self, **ctx: Any) -> None: - self.__dict__ = ctx - - def __str__(self) -> str: - return self.msg_template.format(**self.__dict__) - - def __reduce__(self) -> Tuple[Callable[..., 'PydanticErrorMixin'], Tuple[Type['PydanticErrorMixin'], 'DictStrAny']]: - return cls_kwargs, (self.__class__, self.__dict__) - - -class PydanticTypeError(PydanticErrorMixin, TypeError): - pass - - -class PydanticValueError(PydanticErrorMixin, ValueError): - pass - - -class ConfigError(RuntimeError): - pass - - -class MissingError(PydanticValueError): - msg_template = 'field required' - - -class ExtraError(PydanticValueError): - msg_template = 'extra fields not permitted' - - -class NoneIsNotAllowedError(PydanticTypeError): - code = 'none.not_allowed' - msg_template = 'none is not an allowed value' - - -class NoneIsAllowedError(PydanticTypeError): - code = 'none.allowed' - msg_template = 'value is not none' - - -class WrongConstantError(PydanticValueError): - code = 'const' - - def __str__(self) -> str: - permitted = ', '.join(repr(v) for v in self.permitted) # type: ignore - return f'unexpected value; permitted: {permitted}' - - -class BoolError(PydanticTypeError): - msg_template = 'value could not be parsed to a boolean' - - -class BytesError(PydanticTypeError): - msg_template = 'byte type expected' - - -class DictError(PydanticTypeError): - msg_template = 'value is not a valid dict' - - -class EmailError(PydanticValueError): - msg_template = 'value is not a valid email address' - - -class UrlError(PydanticValueError): - code = 'url' - - -class UrlSchemeError(UrlError): - code = 'url.scheme' - msg_template = 'invalid or missing URL scheme' - - -class UrlSchemePermittedError(UrlError): - code = 'url.scheme' - msg_template = 'URL scheme not permitted' - - def __init__(self, allowed_schemes: Set[str]): - super().__init__(allowed_schemes=allowed_schemes) - - -class UrlUserInfoError(UrlError): - code = 'url.userinfo' - msg_template = 'userinfo required in URL but missing' - - -class UrlHostError(UrlError): - code = 'url.host' - msg_template = 'URL host invalid' - - -class UrlHostTldError(UrlError): - code = 'url.host' - msg_template = 'URL host invalid, top level domain required' - - -class UrlPortError(UrlError): - code = 'url.port' - msg_template = 'URL port invalid, port cannot exceed 65535' - - -class UrlExtraError(UrlError): - code = 'url.extra' - msg_template = 'URL invalid, extra characters found after valid URL: {extra!r}' - - -class EnumMemberError(PydanticTypeError): - code = 'enum' - - def __str__(self) -> str: - permitted = ', '.join(repr(v.value) for v in self.enum_values) # type: ignore - return f'value is not a valid enumeration member; permitted: {permitted}' - - -class IntegerError(PydanticTypeError): - msg_template = 'value is not a valid integer' - - -class FloatError(PydanticTypeError): - msg_template = 'value is not a valid float' - - -class PathError(PydanticTypeError): - msg_template = 'value is not a valid path' - - -class _PathValueError(PydanticValueError): - def __init__(self, *, path: Path) -> None: - super().__init__(path=str(path)) - - -class PathNotExistsError(_PathValueError): - code = 'path.not_exists' - msg_template = 'file or directory at path "{path}" does not exist' - - -class PathNotAFileError(_PathValueError): - code = 'path.not_a_file' - msg_template = 'path "{path}" does not point to a file' - - -class PathNotADirectoryError(_PathValueError): - code = 'path.not_a_directory' - msg_template = 'path "{path}" does not point to a directory' - - -class PyObjectError(PydanticTypeError): - msg_template = 'ensure this value contains valid import path or valid callable: {error_message}' - - -class SequenceError(PydanticTypeError): - msg_template = 'value is not a valid sequence' - - -class IterableError(PydanticTypeError): - msg_template = 'value is not a valid iterable' - - -class ListError(PydanticTypeError): - msg_template = 'value is not a valid list' - - -class SetError(PydanticTypeError): - msg_template = 'value is not a valid set' - - -class FrozenSetError(PydanticTypeError): - msg_template = 'value is not a valid frozenset' - - -class DequeError(PydanticTypeError): - msg_template = 'value is not a valid deque' - - -class TupleError(PydanticTypeError): - msg_template = 'value is not a valid tuple' - - -class TupleLengthError(PydanticValueError): - code = 'tuple.length' - msg_template = 'wrong tuple length {actual_length}, expected {expected_length}' - - def __init__(self, *, actual_length: int, expected_length: int) -> None: - super().__init__(actual_length=actual_length, expected_length=expected_length) - - -class ListMinLengthError(PydanticValueError): - code = 'list.min_items' - msg_template = 'ensure this value has at least {limit_value} items' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class ListMaxLengthError(PydanticValueError): - code = 'list.max_items' - msg_template = 'ensure this value has at most {limit_value} items' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class SetMinLengthError(PydanticValueError): - code = 'set.min_items' - msg_template = 'ensure this value has at least {limit_value} items' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class SetMaxLengthError(PydanticValueError): - code = 'set.max_items' - msg_template = 'ensure this value has at most {limit_value} items' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class AnyStrMinLengthError(PydanticValueError): - code = 'any_str.min_length' - msg_template = 'ensure this value has at least {limit_value} characters' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class AnyStrMaxLengthError(PydanticValueError): - code = 'any_str.max_length' - msg_template = 'ensure this value has at most {limit_value} characters' - - def __init__(self, *, limit_value: int) -> None: - super().__init__(limit_value=limit_value) - - -class StrError(PydanticTypeError): - msg_template = 'str type expected' - - -class StrRegexError(PydanticValueError): - code = 'str.regex' - msg_template = 'string does not match regex "{pattern}"' - - def __init__(self, *, pattern: str) -> None: - super().__init__(pattern=pattern) - - -class _NumberBoundError(PydanticValueError): - def __init__(self, *, limit_value: Union[int, float, Decimal]) -> None: - super().__init__(limit_value=limit_value) - - -class NumberNotGtError(_NumberBoundError): - code = 'number.not_gt' - msg_template = 'ensure this value is greater than {limit_value}' - - -class NumberNotGeError(_NumberBoundError): - code = 'number.not_ge' - msg_template = 'ensure this value is greater than or equal to {limit_value}' - - -class NumberNotLtError(_NumberBoundError): - code = 'number.not_lt' - msg_template = 'ensure this value is less than {limit_value}' - - -class NumberNotLeError(_NumberBoundError): - code = 'number.not_le' - msg_template = 'ensure this value is less than or equal to {limit_value}' - - -class NumberNotMultipleError(PydanticValueError): - code = 'number.not_multiple' - msg_template = 'ensure this value is a multiple of {multiple_of}' - - def __init__(self, *, multiple_of: Union[int, float, Decimal]) -> None: - super().__init__(multiple_of=multiple_of) - - -class DecimalError(PydanticTypeError): - msg_template = 'value is not a valid decimal' - - -class DecimalIsNotFiniteError(PydanticValueError): - code = 'decimal.not_finite' - msg_template = 'value is not a valid decimal' - - -class DecimalMaxDigitsError(PydanticValueError): - code = 'decimal.max_digits' - msg_template = 'ensure that there are no more than {max_digits} digits in total' - - def __init__(self, *, max_digits: int) -> None: - super().__init__(max_digits=max_digits) - - -class DecimalMaxPlacesError(PydanticValueError): - code = 'decimal.max_places' - msg_template = 'ensure that there are no more than {decimal_places} decimal places' - - def __init__(self, *, decimal_places: int) -> None: - super().__init__(decimal_places=decimal_places) - - -class DecimalWholeDigitsError(PydanticValueError): - code = 'decimal.whole_digits' - msg_template = 'ensure that there are no more than {whole_digits} digits before the decimal point' - - def __init__(self, *, whole_digits: int) -> None: - super().__init__(whole_digits=whole_digits) - - -class DateTimeError(PydanticValueError): - msg_template = 'invalid datetime format' - - -class DateError(PydanticValueError): - msg_template = 'invalid date format' - - -class TimeError(PydanticValueError): - msg_template = 'invalid time format' - - -class DurationError(PydanticValueError): - msg_template = 'invalid duration format' - - -class HashableError(PydanticTypeError): - msg_template = 'value is not a valid hashable' - - -class UUIDError(PydanticTypeError): - msg_template = 'value is not a valid uuid' - - -class UUIDVersionError(PydanticValueError): - code = 'uuid.version' - msg_template = 'uuid version {required_version} expected' - - def __init__(self, *, required_version: int) -> None: - super().__init__(required_version=required_version) - - -class ArbitraryTypeError(PydanticTypeError): - code = 'arbitrary_type' - msg_template = 'instance of {expected_arbitrary_type} expected' - - def __init__(self, *, expected_arbitrary_type: Type[Any]) -> None: - super().__init__(expected_arbitrary_type=display_as_type(expected_arbitrary_type)) - - -class ClassError(PydanticTypeError): - code = 'class' - msg_template = 'a class is expected' - - -class SubclassError(PydanticTypeError): - code = 'subclass' - msg_template = 'subclass of {expected_class} expected' - - def __init__(self, *, expected_class: Type[Any]) -> None: - super().__init__(expected_class=display_as_type(expected_class)) - - -class JsonError(PydanticValueError): - msg_template = 'Invalid JSON' - - -class JsonTypeError(PydanticTypeError): - code = 'json' - msg_template = 'JSON object must be str, bytes or bytearray' - - -class PatternError(PydanticValueError): - code = 'regex_pattern' - msg_template = 'Invalid regular expression' - - -class DataclassTypeError(PydanticTypeError): - code = 'dataclass' - msg_template = 'instance of {class_name}, tuple or dict expected' - - -class CallableError(PydanticTypeError): - msg_template = '{value} is not callable' - - -class EnumError(PydanticTypeError): - code = 'enum_instance' - msg_template = '{value} is not a valid Enum instance' - - -class IntEnumError(PydanticTypeError): - code = 'int_enum_instance' - msg_template = '{value} is not a valid IntEnum instance' - - -class IPvAnyAddressError(PydanticValueError): - msg_template = 'value is not a valid IPv4 or IPv6 address' - - -class IPvAnyInterfaceError(PydanticValueError): - msg_template = 'value is not a valid IPv4 or IPv6 interface' - - -class IPvAnyNetworkError(PydanticValueError): - msg_template = 'value is not a valid IPv4 or IPv6 network' - - -class IPv4AddressError(PydanticValueError): - msg_template = 'value is not a valid IPv4 address' - - -class IPv6AddressError(PydanticValueError): - msg_template = 'value is not a valid IPv6 address' - - -class IPv4NetworkError(PydanticValueError): - msg_template = 'value is not a valid IPv4 network' - - -class IPv6NetworkError(PydanticValueError): - msg_template = 'value is not a valid IPv6 network' - - -class IPv4InterfaceError(PydanticValueError): - msg_template = 'value is not a valid IPv4 interface' - - -class IPv6InterfaceError(PydanticValueError): - msg_template = 'value is not a valid IPv6 interface' - - -class ColorError(PydanticValueError): - msg_template = 'value is not a valid color: {reason}' - - -class StrictBoolError(PydanticValueError): - msg_template = 'value is not a valid boolean' - - -class NotDigitError(PydanticValueError): - code = 'payment_card_number.digits' - msg_template = 'card number is not all digits' - - -class LuhnValidationError(PydanticValueError): - code = 'payment_card_number.luhn_check' - msg_template = 'card number is not luhn valid' - - -class InvalidLengthForBrand(PydanticValueError): - code = 'payment_card_number.invalid_length_for_brand' - msg_template = 'Length for a {brand} card must be {required_length}' - - -class InvalidByteSize(PydanticValueError): - msg_template = 'could not parse value and unit from byte string' - - -class InvalidByteSizeUnit(PydanticValueError): - msg_template = 'could not interpret byte unit: {unit}' diff --git a/env/lib/python3.8/site-packages/pydantic/fields.py b/env/lib/python3.8/site-packages/pydantic/fields.py deleted file mode 100644 index 36ea690a..00000000 --- a/env/lib/python3.8/site-packages/pydantic/fields.py +++ /dev/null @@ -1,841 +0,0 @@ -import warnings -from collections import deque -from collections.abc import Iterable as CollectionsIterable -from typing import ( - TYPE_CHECKING, - Any, - Deque, - Dict, - FrozenSet, - Generator, - Iterable, - Iterator, - List, - Mapping, - Optional, - Pattern, - Sequence, - Set, - Tuple, - Type, - TypeVar, - Union, -) - -from . import errors as errors_ -from .class_validators import Validator, make_generic_validator, prep_validators -from .error_wrappers import ErrorWrapper -from .errors import NoneIsNotAllowedError -from .types import Json, JsonWrapper -from .typing import ( - Callable, - ForwardRef, - NoArgAnyCallable, - NoneType, - display_as_type, - get_args, - get_origin, - is_literal_type, - is_new_type, - new_type_supertype, -) -from .utils import PyObjectStr, Representation, lenient_issubclass, sequence_like, smart_deepcopy -from .validators import constant_validator, dict_validator, find_validators, validate_json - -Required: Any = Ellipsis - -T = TypeVar('T') - - -class UndefinedType: - def __repr__(self) -> str: - return 'PydanticUndefined' - - def __copy__(self: T) -> T: - return self - - def __deepcopy__(self: T, _: Any) -> T: - return self - - -Undefined = UndefinedType() - -if TYPE_CHECKING: - from .class_validators import ValidatorsList # noqa: F401 - from .error_wrappers import ErrorList - from .main import BaseConfig, BaseModel # noqa: F401 - from .types import ModelOrDc # noqa: F401 - from .typing import ReprArgs # noqa: F401 - - ValidateReturn = Tuple[Optional[Any], Optional[ErrorList]] - LocStr = Union[Tuple[Union[int, str], ...], str] - BoolUndefined = Union[bool, UndefinedType] - - -class FieldInfo(Representation): - """ - Captures extra information about a field. - """ - - __slots__ = ( - 'default', - 'default_factory', - 'alias', - 'alias_priority', - 'title', - 'description', - 'const', - 'gt', - 'ge', - 'lt', - 'le', - 'multiple_of', - 'min_items', - 'max_items', - 'min_length', - 'max_length', - 'regex', - 'extra', - ) - - def __init__(self, default: Any = Undefined, **kwargs: Any) -> None: - self.default = default - self.default_factory = kwargs.pop('default_factory', None) - self.alias = kwargs.pop('alias', None) - self.alias_priority = kwargs.pop('alias_priority', 2 if self.alias else None) - self.title = kwargs.pop('title', None) - self.description = kwargs.pop('description', None) - self.const = kwargs.pop('const', None) - self.gt = kwargs.pop('gt', None) - self.ge = kwargs.pop('ge', None) - self.lt = kwargs.pop('lt', None) - self.le = kwargs.pop('le', None) - self.multiple_of = kwargs.pop('multiple_of', None) - self.min_items = kwargs.pop('min_items', None) - self.max_items = kwargs.pop('max_items', None) - self.min_length = kwargs.pop('min_length', None) - self.max_length = kwargs.pop('max_length', None) - self.regex = kwargs.pop('regex', None) - self.extra = kwargs - - -def Field( - default: Any = Undefined, - *, - default_factory: Optional[NoArgAnyCallable] = None, - alias: str = None, - title: str = None, - description: str = None, - const: bool = None, - gt: float = None, - ge: float = None, - lt: float = None, - le: float = None, - multiple_of: float = None, - min_items: int = None, - max_items: int = None, - min_length: int = None, - max_length: int = None, - regex: str = None, - **extra: Any, -) -> Any: - """ - Used to provide extra information about a field, either for the model schema or complex validation. Some arguments - apply only to number fields (``int``, ``float``, ``Decimal``) and some apply only to ``str``. - - :param default: since this is replacing the field’s default, its first argument is used - to set the default, use ellipsis (``...``) to indicate the field is required - :param default_factory: callable that will be called when a default value is needed for this field - If both `default` and `default_factory` are set, an error is raised. - :param alias: the public name of the field - :param title: can be any string, used in the schema - :param description: can be any string, used in the schema - :param const: this field is required and *must* take it's default value - :param gt: only applies to numbers, requires the field to be "greater than". The schema - will have an ``exclusiveMinimum`` validation keyword - :param ge: only applies to numbers, requires the field to be "greater than or equal to". The - schema will have a ``minimum`` validation keyword - :param lt: only applies to numbers, requires the field to be "less than". The schema - will have an ``exclusiveMaximum`` validation keyword - :param le: only applies to numbers, requires the field to be "less than or equal to". The - schema will have a ``maximum`` validation keyword - :param multiple_of: only applies to numbers, requires the field to be "a multiple of". The - schema will have a ``multipleOf`` validation keyword - :param min_length: only applies to strings, requires the field to have a minimum length. The - schema will have a ``maximum`` validation keyword - :param max_length: only applies to strings, requires the field to have a maximum length. The - schema will have a ``maxLength`` validation keyword - :param regex: only applies to strings, requires the field match agains a regular expression - pattern string. The schema will have a ``pattern`` validation keyword - :param **extra: any additional keyword arguments will be added as is to the schema - """ - if default is not Undefined and default_factory is not None: - raise ValueError('cannot specify both default and default_factory') - - return FieldInfo( - default, - default_factory=default_factory, - alias=alias, - title=title, - description=description, - const=const, - gt=gt, - ge=ge, - lt=lt, - le=le, - multiple_of=multiple_of, - min_items=min_items, - max_items=max_items, - min_length=min_length, - max_length=max_length, - regex=regex, - **extra, - ) - - -def Schema(default: Any, **kwargs: Any) -> Any: - warnings.warn('`Schema` is deprecated, use `Field` instead', DeprecationWarning) - return Field(default, **kwargs) - - -# used to be an enum but changed to int's for small performance improvement as less access overhead -SHAPE_SINGLETON = 1 -SHAPE_LIST = 2 -SHAPE_SET = 3 -SHAPE_MAPPING = 4 -SHAPE_TUPLE = 5 -SHAPE_TUPLE_ELLIPSIS = 6 -SHAPE_SEQUENCE = 7 -SHAPE_FROZENSET = 8 -SHAPE_ITERABLE = 9 -SHAPE_GENERIC = 10 -SHAPE_DEQUE = 11 -SHAPE_NAME_LOOKUP = { - SHAPE_LIST: 'List[{}]', - SHAPE_SET: 'Set[{}]', - SHAPE_TUPLE_ELLIPSIS: 'Tuple[{}, ...]', - SHAPE_SEQUENCE: 'Sequence[{}]', - SHAPE_FROZENSET: 'FrozenSet[{}]', - SHAPE_ITERABLE: 'Iterable[{}]', - SHAPE_DEQUE: 'Deque[{}]', -} - - -class ModelField(Representation): - __slots__ = ( - 'type_', - 'outer_type_', - 'sub_fields', - 'key_field', - 'validators', - 'pre_validators', - 'post_validators', - 'default', - 'default_factory', - 'required', - 'model_config', - 'name', - 'alias', - 'has_alias', - 'field_info', - 'validate_always', - 'allow_none', - 'shape', - 'class_validators', - 'parse_json', - ) - - def __init__( - self, - *, - name: str, - type_: Type[Any], - class_validators: Optional[Dict[str, Validator]], - model_config: Type['BaseConfig'], - default: Any = None, - default_factory: Optional[NoArgAnyCallable] = None, - required: 'BoolUndefined' = Undefined, - alias: str = None, - field_info: Optional[FieldInfo] = None, - ) -> None: - - self.name: str = name - self.has_alias: bool = bool(alias) - self.alias: str = alias or name - self.type_: Any = type_ - self.outer_type_: Any = type_ - self.class_validators = class_validators or {} - self.default: Any = default - self.default_factory: Optional[NoArgAnyCallable] = default_factory - self.required: 'BoolUndefined' = required - self.model_config = model_config - self.field_info: FieldInfo = field_info or FieldInfo(default) - - self.allow_none: bool = False - self.validate_always: bool = False - self.sub_fields: Optional[List[ModelField]] = None - self.key_field: Optional[ModelField] = None - self.validators: 'ValidatorsList' = [] - self.pre_validators: Optional['ValidatorsList'] = None - self.post_validators: Optional['ValidatorsList'] = None - self.parse_json: bool = False - self.shape: int = SHAPE_SINGLETON - self.model_config.prepare_field(self) - self.prepare() - - def get_default(self) -> Any: - return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory() - - @classmethod - def infer( - cls, - *, - name: str, - value: Any, - annotation: Any, - class_validators: Optional[Dict[str, Validator]], - config: Type['BaseConfig'], - ) -> 'ModelField': - field_info_from_config = config.get_field_info(name) - from .schema import get_annotation_from_field_info - - if isinstance(value, FieldInfo): - field_info = value - value = None if field_info.default_factory is not None else field_info.default - else: - field_info = FieldInfo(value, **field_info_from_config) - required: 'BoolUndefined' = Undefined - if value is Required: - required = True - value = None - elif value is not Undefined: - required = False - field_info.alias = field_info.alias or field_info_from_config.get('alias') - annotation = get_annotation_from_field_info(annotation, field_info, name) - return cls( - name=name, - type_=annotation, - alias=field_info.alias, - class_validators=class_validators, - default=value, - default_factory=field_info.default_factory, - required=required, - model_config=config, - field_info=field_info, - ) - - def set_config(self, config: Type['BaseConfig']) -> None: - self.model_config = config - info_from_config = config.get_field_info(self.name) - config.prepare_field(self) - new_alias = info_from_config.get('alias') - new_alias_priority = info_from_config.get('alias_priority') or 0 - if new_alias and new_alias_priority >= (self.field_info.alias_priority or 0): - self.field_info.alias = new_alias - self.field_info.alias_priority = new_alias_priority - self.alias = new_alias - - @property - def alt_alias(self) -> bool: - return self.name != self.alias - - def prepare(self) -> None: - """ - Prepare the field but inspecting self.default, self.type_ etc. - - Note: this method is **not** idempotent (because _type_analysis is not idempotent), - e.g. calling it it multiple times may modify the field and configure it incorrectly. - """ - - self._set_default_and_type() - if self.type_.__class__ == ForwardRef: - # self.type_ is currently a ForwardRef and there's nothing we can do now, - # user will need to call model.update_forward_refs() - return - - self._type_analysis() - if self.required is Undefined: - self.required = True - self.field_info.default = Required - if self.default is Undefined and self.default_factory is None: - self.default = None - self.populate_validators() - - def _set_default_and_type(self) -> None: - """ - Set the default value, infer the type if needed and check if `None` value is valid. - - Note: to prevent side effects by calling the `default_factory` for nothing, we only call it - when we want to validate the default value i.e. when `validate_all` is set to True. - """ - if self.default_factory is not None: - if self.type_ is None: - raise errors_.ConfigError( - f'you need to set the type of field {self.name!r} when using `default_factory`' - ) - if not self.model_config.validate_all: - return - - default_value = self.get_default() - - if default_value is not None and self.type_ is None: - self.type_ = default_value.__class__ - self.outer_type_ = self.type_ - - if self.type_ is None: - raise errors_.ConfigError(f'unable to infer type for attribute "{self.name}"') - - if self.required is False and default_value is None: - self.allow_none = True - - def _type_analysis(self) -> None: # noqa: C901 (ignore complexity) - # typing interface is horrible, we have to do some ugly checks - if lenient_issubclass(self.type_, JsonWrapper): - self.type_ = self.type_.inner_type - self.parse_json = True - elif lenient_issubclass(self.type_, Json): - self.type_ = Any - self.parse_json = True - elif isinstance(self.type_, TypeVar): - if self.type_.__bound__: - self.type_ = self.type_.__bound__ - elif self.type_.__constraints__: - self.type_ = Union[self.type_.__constraints__] - else: - self.type_ = Any - elif is_new_type(self.type_): - self.type_ = new_type_supertype(self.type_) - - if self.type_ is Any: - if self.required is Undefined: - self.required = False - self.allow_none = True - return - elif self.type_ is Pattern: - # python 3.7 only, Pattern is a typing object but without sub fields - return - elif is_literal_type(self.type_): - return - - origin = get_origin(self.type_) - if origin is None: - # field is not "typing" object eg. Union, Dict, List etc. - # allow None for virtual superclasses of NoneType, e.g. Hashable - if isinstance(self.type_, type) and isinstance(None, self.type_): - self.allow_none = True - return - if origin is Callable: - return - if origin is Union: - types_ = [] - for type_ in get_args(self.type_): - if type_ is NoneType: - if self.required is Undefined: - self.required = False - self.allow_none = True - continue - types_.append(type_) - - if len(types_) == 1: - # Optional[] - self.type_ = types_[0] - # this is the one case where the "outer type" isn't just the original type - self.outer_type_ = self.type_ - # re-run to correctly interpret the new self.type_ - self._type_analysis() - else: - self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_] - return - - if issubclass(origin, Tuple): # type: ignore - self.shape = SHAPE_TUPLE - self.sub_fields = [] - for i, t in enumerate(get_args(self.type_)): - if t is Ellipsis: - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_TUPLE_ELLIPSIS - return - self.sub_fields.append(self._create_sub_type(t, f'{self.name}_{i}')) - return - - if issubclass(origin, List): - # Create self validators - get_validators = getattr(self.type_, '__get_validators__', None) - if get_validators: - self.class_validators.update( - {f'list_{i}': Validator(validator, pre=True) for i, validator in enumerate(get_validators())} - ) - - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_LIST - elif issubclass(origin, Set): - # Create self validators - get_validators = getattr(self.type_, '__get_validators__', None) - if get_validators: - self.class_validators.update( - {f'set_{i}': Validator(validator, pre=True) for i, validator in enumerate(get_validators())} - ) - - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_SET - elif issubclass(origin, FrozenSet): - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_FROZENSET - elif issubclass(origin, Deque): - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_DEQUE - elif issubclass(origin, Sequence): - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_SEQUENCE - elif issubclass(origin, Mapping): - self.key_field = self._create_sub_type(get_args(self.type_)[0], 'key_' + self.name, for_keys=True) - self.type_ = get_args(self.type_)[1] - self.shape = SHAPE_MAPPING - # Equality check as almost everything inherits form Iterable, including str - # check for Iterable and CollectionsIterable, as it could receive one even when declared with the other - elif origin in {Iterable, CollectionsIterable}: - self.type_ = get_args(self.type_)[0] - self.shape = SHAPE_ITERABLE - self.sub_fields = [self._create_sub_type(self.type_, f'{self.name}_type')] - elif issubclass(origin, Type): # type: ignore - return - elif hasattr(origin, '__get_validators__') or self.model_config.arbitrary_types_allowed: - # Is a Pydantic-compatible generic that handles itself - # or we have arbitrary_types_allowed = True - self.shape = SHAPE_GENERIC - self.sub_fields = [self._create_sub_type(t, f'{self.name}_{i}') for i, t in enumerate(get_args(self.type_))] - self.type_ = origin - return - else: - raise TypeError(f'Fields of type "{origin}" are not supported.') - - # type_ has been refined eg. as the type of a List and sub_fields needs to be populated - self.sub_fields = [self._create_sub_type(self.type_, '_' + self.name)] - - def _create_sub_type(self, type_: Type[Any], name: str, *, for_keys: bool = False) -> 'ModelField': - return self.__class__( - type_=type_, - name=name, - class_validators=None if for_keys else {k: v for k, v in self.class_validators.items() if v.each_item}, - model_config=self.model_config, - ) - - def populate_validators(self) -> None: - """ - Prepare self.pre_validators, self.validators, and self.post_validators based on self.type_'s __get_validators__ - and class validators. This method should be idempotent, e.g. it should be safe to call multiple times - without mis-configuring the field. - """ - self.validate_always = getattr(self.type_, 'validate_always', False) or any( - v.always for v in self.class_validators.values() - ) - - class_validators_ = self.class_validators.values() - if not self.sub_fields or self.shape == SHAPE_GENERIC: - get_validators = getattr(self.type_, '__get_validators__', None) - v_funcs = ( - *[v.func for v in class_validators_ if v.each_item and v.pre], - *(get_validators() if get_validators else list(find_validators(self.type_, self.model_config))), - *[v.func for v in class_validators_ if v.each_item and not v.pre], - ) - self.validators = prep_validators(v_funcs) - - self.pre_validators = [] - self.post_validators = [] - - if self.field_info and self.field_info.const: - self.post_validators.append(make_generic_validator(constant_validator)) - - if class_validators_: - self.pre_validators += prep_validators(v.func for v in class_validators_ if not v.each_item and v.pre) - self.post_validators += prep_validators(v.func for v in class_validators_ if not v.each_item and not v.pre) - - if self.parse_json: - self.pre_validators.append(make_generic_validator(validate_json)) - - self.pre_validators = self.pre_validators or None - self.post_validators = self.post_validators or None - - def validate( - self, v: Any, values: Dict[str, Any], *, loc: 'LocStr', cls: Optional['ModelOrDc'] = None - ) -> 'ValidateReturn': - - errors: Optional['ErrorList'] - if self.pre_validators: - v, errors = self._apply_validators(v, values, loc, cls, self.pre_validators) - if errors: - return v, errors - - if v is None: - if self.allow_none: - if self.post_validators: - return self._apply_validators(v, values, loc, cls, self.post_validators) - else: - return None, None - else: - return v, ErrorWrapper(NoneIsNotAllowedError(), loc) - - if self.shape == SHAPE_SINGLETON: - v, errors = self._validate_singleton(v, values, loc, cls) - elif self.shape == SHAPE_MAPPING: - v, errors = self._validate_mapping(v, values, loc, cls) - elif self.shape == SHAPE_TUPLE: - v, errors = self._validate_tuple(v, values, loc, cls) - elif self.shape == SHAPE_ITERABLE: - v, errors = self._validate_iterable(v, values, loc, cls) - elif self.shape == SHAPE_GENERIC: - v, errors = self._apply_validators(v, values, loc, cls, self.validators) - else: - # sequence, list, set, generator, tuple with ellipsis, frozen set - v, errors = self._validate_sequence_like(v, values, loc, cls) - - if not errors and self.post_validators: - v, errors = self._apply_validators(v, values, loc, cls, self.post_validators) - return v, errors - - def _validate_sequence_like( # noqa: C901 (ignore complexity) - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'] - ) -> 'ValidateReturn': - """ - Validate sequence-like containers: lists, tuples, sets and generators - Note that large if-else blocks are necessary to enable Cython - optimization, which is why we disable the complexity check above. - """ - if not sequence_like(v): - e: errors_.PydanticTypeError - if self.shape == SHAPE_LIST: - e = errors_.ListError() - elif self.shape == SHAPE_SET: - e = errors_.SetError() - elif self.shape == SHAPE_FROZENSET: - e = errors_.FrozenSetError() - else: - e = errors_.SequenceError() - return v, ErrorWrapper(e, loc) - - loc = loc if isinstance(loc, tuple) else (loc,) - result = [] - errors: List[ErrorList] = [] - for i, v_ in enumerate(v): - v_loc = *loc, i - r, ee = self._validate_singleton(v_, values, v_loc, cls) - if ee: - errors.append(ee) - else: - result.append(r) - - if errors: - return v, errors - - converted: Union[List[Any], Set[Any], FrozenSet[Any], Tuple[Any, ...], Iterator[Any], Deque[Any]] = result - - if self.shape == SHAPE_SET: - converted = set(result) - elif self.shape == SHAPE_FROZENSET: - converted = frozenset(result) - elif self.shape == SHAPE_TUPLE_ELLIPSIS: - converted = tuple(result) - elif self.shape == SHAPE_DEQUE: - converted = deque(result) - elif self.shape == SHAPE_SEQUENCE: - if isinstance(v, tuple): - converted = tuple(result) - elif isinstance(v, set): - converted = set(result) - elif isinstance(v, Generator): - converted = iter(result) - elif isinstance(v, deque): - converted = deque(result) - return converted, None - - def _validate_iterable( - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'] - ) -> 'ValidateReturn': - """ - Validate Iterables. - - This intentionally doesn't validate values to allow infinite generators. - """ - - try: - iterable = iter(v) - except TypeError: - return v, ErrorWrapper(errors_.IterableError(), loc) - return iterable, None - - def _validate_tuple( - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'] - ) -> 'ValidateReturn': - e: Optional[Exception] = None - if not sequence_like(v): - e = errors_.TupleError() - else: - actual_length, expected_length = len(v), len(self.sub_fields) # type: ignore - if actual_length != expected_length: - e = errors_.TupleLengthError(actual_length=actual_length, expected_length=expected_length) - - if e: - return v, ErrorWrapper(e, loc) - - loc = loc if isinstance(loc, tuple) else (loc,) - result = [] - errors: List[ErrorList] = [] - for i, (v_, field) in enumerate(zip(v, self.sub_fields)): # type: ignore - v_loc = *loc, i - r, ee = field.validate(v_, values, loc=v_loc, cls=cls) - if ee: - errors.append(ee) - else: - result.append(r) - - if errors: - return v, errors - else: - return tuple(result), None - - def _validate_mapping( - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'] - ) -> 'ValidateReturn': - try: - v_iter = dict_validator(v) - except TypeError as exc: - return v, ErrorWrapper(exc, loc) - - loc = loc if isinstance(loc, tuple) else (loc,) - result, errors = {}, [] - for k, v_ in v_iter.items(): - v_loc = *loc, '__key__' - key_result, key_errors = self.key_field.validate(k, values, loc=v_loc, cls=cls) # type: ignore - if key_errors: - errors.append(key_errors) - continue - - v_loc = *loc, k - value_result, value_errors = self._validate_singleton(v_, values, v_loc, cls) - if value_errors: - errors.append(value_errors) - continue - - result[key_result] = value_result - if errors: - return v, errors - else: - return result, None - - def _validate_singleton( - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'] - ) -> 'ValidateReturn': - if self.sub_fields: - errors = [] - for field in self.sub_fields: - value, error = field.validate(v, values, loc=loc, cls=cls) - if error: - errors.append(error) - else: - return value, None - return v, errors - else: - return self._apply_validators(v, values, loc, cls, self.validators) - - def _apply_validators( - self, v: Any, values: Dict[str, Any], loc: 'LocStr', cls: Optional['ModelOrDc'], validators: 'ValidatorsList' - ) -> 'ValidateReturn': - for validator in validators: - try: - v = validator(cls, v, values, self, self.model_config) - except (ValueError, TypeError, AssertionError) as exc: - return v, ErrorWrapper(exc, loc) - return v, None - - def include_in_schema(self) -> bool: - """ - False if this is a simple field just allowing None as used in Unions/Optional. - """ - return self.type_ != NoneType - - def is_complex(self) -> bool: - """ - Whether the field is "complex" eg. env variables should be parsed as JSON. - """ - from .main import BaseModel # noqa: F811 - - return ( - self.shape != SHAPE_SINGLETON - or lenient_issubclass(self.type_, (BaseModel, list, set, frozenset, dict)) - or hasattr(self.type_, '__pydantic_model__') # pydantic dataclass - ) - - def _type_display(self) -> PyObjectStr: - t = display_as_type(self.type_) - - # have to do this since display_as_type(self.outer_type_) is different (and wrong) on python 3.6 - if self.shape == SHAPE_MAPPING: - t = f'Mapping[{display_as_type(self.key_field.type_)}, {t}]' # type: ignore - elif self.shape == SHAPE_TUPLE: - t = 'Tuple[{}]'.format(', '.join(display_as_type(f.type_) for f in self.sub_fields)) # type: ignore - elif self.shape == SHAPE_GENERIC: - assert self.sub_fields - t = '{}[{}]'.format( - display_as_type(self.type_), ', '.join(display_as_type(f.type_) for f in self.sub_fields) - ) - elif self.shape != SHAPE_SINGLETON: - t = SHAPE_NAME_LOOKUP[self.shape].format(t) - - if self.allow_none and (self.shape != SHAPE_SINGLETON or not self.sub_fields): - t = f'Optional[{t}]' - return PyObjectStr(t) - - def __repr_args__(self) -> 'ReprArgs': - args = [('name', self.name), ('type', self._type_display()), ('required', self.required)] - - if not self.required: - if self.default_factory is not None: - args.append(('default_factory', f'')) - else: - args.append(('default', self.default)) - - if self.alt_alias: - args.append(('alias', self.alias)) - return args - - -class ModelPrivateAttr(Representation): - __slots__ = ('default', 'default_factory') - - def __init__(self, default: Any = Undefined, *, default_factory: Optional[NoArgAnyCallable] = None) -> None: - self.default = default - self.default_factory = default_factory - - def get_default(self) -> Any: - return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory() - - def __eq__(self, other: Any) -> bool: - return isinstance(other, self.__class__) and (self.default, self.default_factory) == ( - other.default, - other.default_factory, - ) - - -def PrivateAttr( - default: Any = Undefined, - *, - default_factory: Optional[NoArgAnyCallable] = None, -) -> Any: - """ - Indicates that attribute is only used internally and never mixed with regular fields. - - Types or values of private attrs are not checked by pydantic and it's up to you to keep them relevant. - - Private attrs are stored in model __slots__. - - :param default: the attribute’s default value - :param default_factory: callable that will be called when a default value is needed for this attribute - If both `default` and `default_factory` are set, an error is raised. - """ - if default is not Undefined and default_factory is not None: - raise ValueError('cannot specify both default and default_factory') - - return ModelPrivateAttr( - default, - default_factory=default_factory, - ) diff --git a/env/lib/python3.8/site-packages/pydantic/generics.py b/env/lib/python3.8/site-packages/pydantic/generics.py deleted file mode 100644 index 76be7599..00000000 --- a/env/lib/python3.8/site-packages/pydantic/generics.py +++ /dev/null @@ -1,159 +0,0 @@ -import sys -from typing import ( - TYPE_CHECKING, - Any, - ClassVar, - Dict, - Generic, - Optional, - Tuple, - Type, - TypeVar, - Union, - cast, - get_type_hints, -) - -from .class_validators import gather_all_validators -from .fields import FieldInfo, ModelField -from .main import BaseModel, create_model -from .typing import get_origin -from .utils import lenient_issubclass - -_generic_types_cache: Dict[Tuple[Type[Any], Union[Any, Tuple[Any, ...]]], Type[BaseModel]] = {} -GenericModelT = TypeVar('GenericModelT', bound='GenericModel') -TypeVarType = Any # since mypy doesn't allow the use of TypeVar as a type - - -class GenericModel(BaseModel): - __slots__ = () - __concrete__: ClassVar[bool] = False - - if TYPE_CHECKING: - # Putting this in a TYPE_CHECKING block allows us to replace `if Generic not in cls.__bases__` with - # `not hasattr(cls, "__parameters__")`. This means we don't need to force non-concrete subclasses of - # `GenericModel` to also inherit from `Generic`, which would require changes to the use of `create_model` below. - __parameters__: ClassVar[Tuple[TypeVarType, ...]] - - # Setting the return type as Type[Any] instead of Type[BaseModel] prevents PyCharm warnings - def __class_getitem__(cls: Type[GenericModelT], params: Union[Type[Any], Tuple[Type[Any], ...]]) -> Type[Any]: - cached = _generic_types_cache.get((cls, params)) - if cached is not None: - return cached - if cls.__concrete__ and Generic not in cls.__bases__: - raise TypeError('Cannot parameterize a concrete instantiation of a generic model') - if not isinstance(params, tuple): - params = (params,) - if cls is GenericModel and any(isinstance(param, TypeVar) for param in params): - raise TypeError('Type parameters should be placed on typing.Generic, not GenericModel') - if not hasattr(cls, '__parameters__'): - raise TypeError(f'Type {cls.__name__} must inherit from typing.Generic before being parameterized') - - check_parameters_count(cls, params) - typevars_map: Dict[TypeVarType, Type[Any]] = dict(zip(cls.__parameters__, params)) - type_hints = get_type_hints(cls).items() - instance_type_hints = {k: v for k, v in type_hints if get_origin(v) is not ClassVar} - concrete_type_hints: Dict[str, Type[Any]] = { - k: resolve_type_hint(v, typevars_map) for k, v in instance_type_hints.items() - } - - model_name = cls.__concrete_name__(params) - validators = gather_all_validators(cls) - fields = _build_generic_fields(cls.__fields__, concrete_type_hints, typevars_map) - model_module, called_globally = get_caller_frame_info() - created_model = cast( - Type[GenericModel], # casting ensures mypy is aware of the __concrete__ and __parameters__ attributes - create_model( - model_name, - __module__=model_module or cls.__module__, - __base__=cls, - __config__=None, - __validators__=validators, - **fields, - ), - ) - - if called_globally: # create global reference and therefore allow pickling - object_by_reference = None - reference_name = model_name - reference_module_globals = sys.modules[created_model.__module__].__dict__ - while object_by_reference is not created_model: - object_by_reference = reference_module_globals.setdefault(reference_name, created_model) - reference_name += '_' - - created_model.Config = cls.Config - concrete = all(not _is_typevar(v) for v in concrete_type_hints.values()) - created_model.__concrete__ = concrete - if not concrete: - parameters = tuple(v for v in concrete_type_hints.values() if _is_typevar(v)) - parameters = tuple({k: None for k in parameters}.keys()) # get unique params while maintaining order - created_model.__parameters__ = parameters - _generic_types_cache[(cls, params)] = created_model - if len(params) == 1: - _generic_types_cache[(cls, params[0])] = created_model - return created_model - - @classmethod - def __concrete_name__(cls: Type[Any], params: Tuple[Type[Any], ...]) -> str: - """ - This method can be overridden to achieve a custom naming scheme for GenericModels - """ - param_names = [param.__name__ if hasattr(param, '__name__') else str(param) for param in params] - params_component = ', '.join(param_names) - return f'{cls.__name__}[{params_component}]' - - -def resolve_type_hint(type_: Any, typevars_map: Dict[Any, Any]) -> Type[Any]: - if get_origin(type_) and getattr(type_, '__parameters__', None): - concrete_type_args = tuple([typevars_map[x] for x in type_.__parameters__]) - return type_[concrete_type_args] - return typevars_map.get(type_, type_) - - -def check_parameters_count(cls: Type[GenericModel], parameters: Tuple[Any, ...]) -> None: - actual = len(parameters) - expected = len(cls.__parameters__) - if actual != expected: - description = 'many' if actual > expected else 'few' - raise TypeError(f'Too {description} parameters for {cls.__name__}; actual {actual}, expected {expected}') - - -def _build_generic_fields( - raw_fields: Dict[str, ModelField], - concrete_type_hints: Dict[str, Type[Any]], - typevars_map: Dict[TypeVarType, Type[Any]], -) -> Dict[str, Tuple[Type[Any], FieldInfo]]: - return { - k: (_parameterize_generic_field(v, typevars_map), raw_fields[k].field_info) - for k, v in concrete_type_hints.items() - if k in raw_fields - } - - -def _parameterize_generic_field(field_type: Type[Any], typevars_map: Dict[TypeVarType, Type[Any]]) -> Type[Any]: - if lenient_issubclass(field_type, GenericModel) and not field_type.__concrete__: - parameters = tuple(typevars_map.get(param, param) for param in field_type.__parameters__) - field_type = field_type[parameters] - return field_type - - -def _is_typevar(v: Any) -> bool: - return isinstance(v, TypeVar) - - -def get_caller_frame_info() -> Tuple[Optional[str], bool]: - """ - Used inside a function to check whether it was called globally - - Will only work against non-compiled code, therefore used only in pydantic.generics - - :returns Tuple[module_name, called_globally] - """ - try: - previous_caller_frame = sys._getframe(2) - except ValueError as e: - raise RuntimeError('This function must be used inside another function') from e - except AttributeError: # sys module does not have _getframe function, so there's nothing we can do about it - return None, False - frame_globals = previous_caller_frame.f_globals - return frame_globals.get('__name__'), previous_caller_frame.f_locals is frame_globals diff --git a/env/lib/python3.8/site-packages/pydantic/json.py b/env/lib/python3.8/site-packages/pydantic/json.py deleted file mode 100644 index 9ce9d57d..00000000 --- a/env/lib/python3.8/site-packages/pydantic/json.py +++ /dev/null @@ -1,86 +0,0 @@ -import datetime -from collections import deque -from decimal import Decimal -from enum import Enum -from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network -from pathlib import Path -from types import GeneratorType -from typing import Any, Callable, Dict, Type, Union -from uuid import UUID - -from .color import Color -from .types import SecretBytes, SecretStr - -__all__ = 'pydantic_encoder', 'custom_pydantic_encoder', 'timedelta_isoformat' - - -def isoformat(o: Union[datetime.date, datetime.time]) -> str: - return o.isoformat() - - -ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = { - bytes: lambda o: o.decode(), - Color: str, - datetime.date: isoformat, - datetime.datetime: isoformat, - datetime.time: isoformat, - datetime.timedelta: lambda td: td.total_seconds(), - Decimal: float, - Enum: lambda o: o.value, - frozenset: list, - deque: list, - GeneratorType: list, - IPv4Address: str, - IPv4Interface: str, - IPv4Network: str, - IPv6Address: str, - IPv6Interface: str, - IPv6Network: str, - Path: str, - SecretBytes: str, - SecretStr: str, - set: list, - UUID: str, -} - - -def pydantic_encoder(obj: Any) -> Any: - from dataclasses import asdict, is_dataclass - - from .main import BaseModel - - if isinstance(obj, BaseModel): - return obj.dict() - elif is_dataclass(obj): - return asdict(obj) - - # Check the class type and its superclasses for a matching encoder - for base in obj.__class__.__mro__[:-1]: - try: - encoder = ENCODERS_BY_TYPE[base] - except KeyError: - continue - return encoder(obj) - else: # We have exited the for loop without finding a suitable encoder - raise TypeError(f"Object of type '{obj.__class__.__name__}' is not JSON serializable") - - -def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]], obj: Any) -> Any: - # Check the class type and its superclasses for a matching encoder - for base in obj.__class__.__mro__[:-1]: - try: - encoder = type_encoders[base] - except KeyError: - continue - return encoder(obj) - else: # We have exited the for loop without finding a suitable encoder - return pydantic_encoder(obj) - - -def timedelta_isoformat(td: datetime.timedelta) -> str: - """ - ISO 8601 encoding for timedeltas. - """ - minutes, seconds = divmod(td.seconds, 60) - hours, minutes = divmod(minutes, 60) - return f'P{td.days}DT{hours:d}H{minutes:d}M{seconds:d}.{td.microseconds:06d}S' diff --git a/env/lib/python3.8/site-packages/pydantic/main.py b/env/lib/python3.8/site-packages/pydantic/main.py deleted file mode 100644 index 3d57b1bb..00000000 --- a/env/lib/python3.8/site-packages/pydantic/main.py +++ /dev/null @@ -1,1014 +0,0 @@ -import json -import sys -import warnings -from abc import ABCMeta -from copy import deepcopy -from enum import Enum -from functools import partial -from pathlib import Path -from types import FunctionType -from typing import ( - TYPE_CHECKING, - AbstractSet, - Any, - Callable, - Dict, - List, - Mapping, - Optional, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, - no_type_check, - overload, -) - -from .class_validators import ValidatorGroup, extract_root_validators, extract_validators, inherit_validators -from .error_wrappers import ErrorWrapper, ValidationError -from .errors import ConfigError, DictError, ExtraError, MissingError -from .fields import SHAPE_MAPPING, ModelField, ModelPrivateAttr, PrivateAttr, Undefined -from .json import custom_pydantic_encoder, pydantic_encoder -from .parse import Protocol, load_file, load_str_bytes -from .schema import default_ref_template, model_schema -from .types import PyObject, StrBytes -from .typing import AnyCallable, ForwardRef, get_origin, is_classvar, resolve_annotations, update_field_forward_refs -from .utils import ( - ROOT_KEY, - ClassAttribute, - GetterDict, - Representation, - ValueItems, - generate_model_signature, - is_valid_field, - is_valid_private_name, - lenient_issubclass, - sequence_like, - smart_deepcopy, - unique_list, - validate_field_name, -) - -if TYPE_CHECKING: - from inspect import Signature - - import typing_extensions - - from .class_validators import ValidatorListDict - from .types import ModelOrDc - from .typing import ( # noqa: F401 - AbstractSetIntStr, - CallableGenerator, - DictAny, - DictStrAny, - MappingIntStrAny, - ReprArgs, - SetStr, - TupleGenerator, - ) - - ConfigType = Type['BaseConfig'] - Model = TypeVar('Model', bound='BaseModel') - - class SchemaExtraCallable(typing_extensions.Protocol): - @overload - def __call__(self, schema: Dict[str, Any]) -> None: - pass - - @overload # noqa: F811 - def __call__(self, schema: Dict[str, Any], model_class: Type['Model']) -> None: # noqa: F811 - pass - - -else: - SchemaExtraCallable = Callable[..., None] - -try: - import cython # type: ignore -except ImportError: - compiled: bool = False -else: # pragma: no cover - try: - compiled = cython.compiled - except AttributeError: - compiled = False - -__all__ = 'BaseConfig', 'BaseModel', 'Extra', 'compiled', 'create_model', 'validate_model' - - -class Extra(str, Enum): - allow = 'allow' - ignore = 'ignore' - forbid = 'forbid' - - -class BaseConfig: - title = None - anystr_strip_whitespace = False - min_anystr_length = None - max_anystr_length = None - validate_all = False - extra = Extra.ignore - allow_mutation = True - allow_population_by_field_name = False - use_enum_values = False - fields: Dict[str, Union[str, Dict[str, str]]] = {} - validate_assignment = False - error_msg_templates: Dict[str, str] = {} - arbitrary_types_allowed = False - orm_mode: bool = False - getter_dict: Type[GetterDict] = GetterDict - alias_generator: Optional[Callable[[str], str]] = None - keep_untouched: Tuple[type, ...] = () - schema_extra: Union[Dict[str, Any], 'SchemaExtraCallable'] = {} - json_loads: Callable[[str], Any] = json.loads - json_dumps: Callable[..., str] = json.dumps - json_encoders: Dict[Type[Any], AnyCallable] = {} - underscore_attrs_are_private: bool = False - - @classmethod - def get_field_info(cls, name: str) -> Dict[str, Any]: - fields_value = cls.fields.get(name) - - if isinstance(fields_value, str): - field_info: Dict[str, Any] = {'alias': fields_value} - elif isinstance(fields_value, dict): - field_info = fields_value - else: - field_info = {} - - if 'alias' in field_info: - field_info.setdefault('alias_priority', 2) - - if field_info.get('alias_priority', 0) <= 1 and cls.alias_generator: - alias = cls.alias_generator(name) - if not isinstance(alias, str): - raise TypeError(f'Config.alias_generator must return str, not {alias.__class__}') - field_info.update(alias=alias, alias_priority=1) - return field_info - - @classmethod - def prepare_field(cls, field: 'ModelField') -> None: - """ - Optional hook to check or modify fields during model creation. - """ - pass - - -def inherit_config(self_config: 'ConfigType', parent_config: 'ConfigType') -> 'ConfigType': - if not self_config: - base_classes = (parent_config,) - elif self_config == parent_config: - base_classes = (self_config,) - else: - base_classes = self_config, parent_config # type: ignore - return type('Config', base_classes, {}) - - -EXTRA_LINK = 'https://pydantic-docs.helpmanual.io/usage/model_config/' - - -def prepare_config(config: Type[BaseConfig], cls_name: str) -> None: - if not isinstance(config.extra, Extra): - try: - config.extra = Extra(config.extra) - except ValueError: - raise ValueError(f'"{cls_name}": {config.extra} is not a valid value for "extra"') - - if hasattr(config, 'allow_population_by_alias'): - warnings.warn( - f'{cls_name}: "allow_population_by_alias" is deprecated and replaced by "allow_population_by_field_name"', - DeprecationWarning, - ) - config.allow_population_by_field_name = config.allow_population_by_alias # type: ignore - - if hasattr(config, 'case_insensitive') and any('BaseSettings.Config' in c.__qualname__ for c in config.__mro__): - warnings.warn( - f'{cls_name}: "case_insensitive" is deprecated on BaseSettings config and replaced by ' - f'"case_sensitive" (default False)', - DeprecationWarning, - ) - config.case_sensitive = not config.case_insensitive # type: ignore - - -def validate_custom_root_type(fields: Dict[str, ModelField]) -> None: - if len(fields) > 1: - raise ValueError('__root__ cannot be mixed with other fields') - - -UNTOUCHED_TYPES = FunctionType, property, type, classmethod, staticmethod - -# Note `ModelMetaclass` refers to `BaseModel`, but is also used to *create* `BaseModel`, so we need to add this extra -# (somewhat hacky) boolean to keep track of whether we've created the `BaseModel` class yet, and therefore whether it's -# safe to refer to it. If it *hasn't* been created, we assume that the `__new__` call we're in the middle of is for -# the `BaseModel` class, since that's defined immediately after the metaclass. -_is_base_model_class_defined = False - - -class ModelMetaclass(ABCMeta): - @no_type_check # noqa C901 - def __new__(mcs, name, bases, namespace, **kwargs): # noqa C901 - fields: Dict[str, ModelField] = {} - config = BaseConfig - validators: 'ValidatorListDict' = {} - - pre_root_validators, post_root_validators = [], [] - private_attributes: Dict[str, ModelPrivateAttr] = {} - slots: Set[str] = namespace.get('__slots__', ()) - slots = {slots} if isinstance(slots, str) else set(slots) - - for base in reversed(bases): - if _is_base_model_class_defined and issubclass(base, BaseModel) and base != BaseModel: - fields.update(smart_deepcopy(base.__fields__)) - config = inherit_config(base.__config__, config) - validators = inherit_validators(base.__validators__, validators) - pre_root_validators += base.__pre_root_validators__ - post_root_validators += base.__post_root_validators__ - private_attributes.update(base.__private_attributes__) - - config = inherit_config(namespace.get('Config'), config) - validators = inherit_validators(extract_validators(namespace), validators) - vg = ValidatorGroup(validators) - - for f in fields.values(): - f.set_config(config) - extra_validators = vg.get_validators(f.name) - if extra_validators: - f.class_validators.update(extra_validators) - # re-run prepare to add extra validators - f.populate_validators() - - prepare_config(config, name) - - class_vars = set() - if (namespace.get('__module__'), namespace.get('__qualname__')) != ('pydantic.main', 'BaseModel'): - annotations = resolve_annotations(namespace.get('__annotations__', {}), namespace.get('__module__', None)) - untouched_types = UNTOUCHED_TYPES + config.keep_untouched - # annotation only fields need to come first in fields - for ann_name, ann_type in annotations.items(): - if is_classvar(ann_type): - class_vars.add(ann_name) - elif is_valid_field(ann_name): - validate_field_name(bases, ann_name) - value = namespace.get(ann_name, Undefined) - if ( - isinstance(value, untouched_types) - and ann_type != PyObject - and not lenient_issubclass(get_origin(ann_type), Type) - ): - continue - fields[ann_name] = inferred = ModelField.infer( - name=ann_name, - value=value, - annotation=ann_type, - class_validators=vg.get_validators(ann_name), - config=config, - ) - elif ann_name not in namespace and config.underscore_attrs_are_private: - private_attributes[ann_name] = PrivateAttr() - - for var_name, value in namespace.items(): - can_be_changed = var_name not in class_vars and not isinstance(value, untouched_types) - if isinstance(value, ModelPrivateAttr): - if not is_valid_private_name(var_name): - raise NameError( - f'Private attributes "{var_name}" must not be a valid field name; ' - f'Use sunder or dunder names, e. g. "_{var_name}" or "__{var_name}__"' - ) - private_attributes[var_name] = value - elif config.underscore_attrs_are_private and is_valid_private_name(var_name) and can_be_changed: - private_attributes[var_name] = PrivateAttr(default=value) - elif is_valid_field(var_name) and var_name not in annotations and can_be_changed: - validate_field_name(bases, var_name) - inferred = ModelField.infer( - name=var_name, - value=value, - annotation=annotations.get(var_name), - class_validators=vg.get_validators(var_name), - config=config, - ) - if var_name in fields and inferred.type_ != fields[var_name].type_: - raise TypeError( - f'The type of {name}.{var_name} differs from the new default value; ' - f'if you wish to change the type of this field, please use a type annotation' - ) - fields[var_name] = inferred - - _custom_root_type = ROOT_KEY in fields - if _custom_root_type: - validate_custom_root_type(fields) - vg.check_for_unused() - if config.json_encoders: - json_encoder = partial(custom_pydantic_encoder, config.json_encoders) - else: - json_encoder = pydantic_encoder - pre_rv_new, post_rv_new = extract_root_validators(namespace) - - exclude_from_namespace = fields | private_attributes.keys() | {'__slots__'} - new_namespace = { - '__config__': config, - '__fields__': fields, - '__validators__': vg.validators, - '__pre_root_validators__': unique_list(pre_root_validators + pre_rv_new), - '__post_root_validators__': unique_list(post_root_validators + post_rv_new), - '__schema_cache__': {}, - '__json_encoder__': staticmethod(json_encoder), - '__custom_root_type__': _custom_root_type, - '__private_attributes__': private_attributes, - '__slots__': slots | private_attributes.keys(), - **{n: v for n, v in namespace.items() if n not in exclude_from_namespace}, - } - - cls = super().__new__(mcs, name, bases, new_namespace, **kwargs) - # set __signature__ attr only for model class, but not for its instances - cls.__signature__ = ClassAttribute('__signature__', generate_model_signature(cls.__init__, fields, config)) - return cls - - -object_setattr = object.__setattr__ - - -class BaseModel(Representation, metaclass=ModelMetaclass): - if TYPE_CHECKING: - # populated by the metaclass, defined here to help IDEs only - __fields__: Dict[str, ModelField] = {} - __validators__: Dict[str, AnyCallable] = {} - __pre_root_validators__: List[AnyCallable] - __post_root_validators__: List[Tuple[bool, AnyCallable]] - __config__: Type[BaseConfig] = BaseConfig - __root__: Any = None - __json_encoder__: Callable[[Any], Any] = lambda x: x - __schema_cache__: 'DictAny' = {} - __custom_root_type__: bool = False - __signature__: 'Signature' - __private_attributes__: Dict[str, Any] - __fields_set__: SetStr = set() - - Config = BaseConfig - __slots__ = ('__dict__', '__fields_set__') - __doc__ = '' # Null out the Representation docstring - - def __init__(__pydantic_self__, **data: Any) -> None: - """ - Create a new model by parsing and validating input data from keyword arguments. - - Raises ValidationError if the input data cannot be parsed to form a valid model. - """ - # Uses something other than `self` the first arg to allow "self" as a settable attribute - values, fields_set, validation_error = validate_model(__pydantic_self__.__class__, data) - if validation_error: - raise validation_error - object_setattr(__pydantic_self__, '__dict__', values) - object_setattr(__pydantic_self__, '__fields_set__', fields_set) - __pydantic_self__._init_private_attributes() - - @no_type_check - def __setattr__(self, name, value): # noqa: C901 (ignore complexity) - if name in self.__private_attributes__: - return object_setattr(self, name, value) - - if self.__config__.extra is not Extra.allow and name not in self.__fields__: - raise ValueError(f'"{self.__class__.__name__}" object has no field "{name}"') - elif not self.__config__.allow_mutation: - raise TypeError(f'"{self.__class__.__name__}" is immutable and does not support item assignment') - elif self.__config__.validate_assignment: - new_values = {**self.__dict__, name: value} - - for validator in self.__pre_root_validators__: - try: - new_values = validator(self.__class__, new_values) - except (ValueError, TypeError, AssertionError) as exc: - raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], self.__class__) - - known_field = self.__fields__.get(name, None) - if known_field: - # We want to - # - make sure validators are called without the current value for this field inside `values` - # - keep other values (e.g. submodels) untouched (using `BaseModel.dict()` will change them into dicts) - # - keep the order of the fields - dict_without_original_value = {k: v for k, v in self.__dict__.items() if k != name} - value, error_ = known_field.validate(value, dict_without_original_value, loc=name, cls=self.__class__) - if error_: - raise ValidationError([error_], self.__class__) - else: - new_values[name] = value - - errors = [] - for skip_on_failure, validator in self.__post_root_validators__: - if skip_on_failure and errors: - continue - try: - new_values = validator(self.__class__, new_values) - except (ValueError, TypeError, AssertionError) as exc: - errors.append(ErrorWrapper(exc, loc=ROOT_KEY)) - if errors: - raise ValidationError(errors, self.__class__) - - self.__dict__[name] = value - self.__fields_set__.add(name) - - def __getstate__(self) -> 'DictAny': - return { - '__dict__': self.__dict__, - '__fields_set__': self.__fields_set__, - '__private_attribute_values__': {k: getattr(self, k, Undefined) for k in self.__private_attributes__}, - } - - def __setstate__(self, state: 'DictAny') -> None: - object_setattr(self, '__dict__', state['__dict__']) - object_setattr(self, '__fields_set__', state['__fields_set__']) - for name, value in state.get('__private_attribute_values__', {}).items(): - if value is not Undefined: - object_setattr(self, name, value) - - def _init_private_attributes(self) -> None: - for name, private_attr in self.__private_attributes__.items(): - default = private_attr.get_default() - if default is not Undefined: - object_setattr(self, name, default) - - def dict( - self, - *, - include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - by_alias: bool = False, - skip_defaults: bool = None, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - ) -> 'DictStrAny': - """ - Generate a dictionary representation of the model, optionally specifying which fields to include or exclude. - - """ - if skip_defaults is not None: - warnings.warn( - f'{self.__class__.__name__}.dict(): "skip_defaults" is deprecated and replaced by "exclude_unset"', - DeprecationWarning, - ) - exclude_unset = skip_defaults - - return dict( - self._iter( - to_dict=True, - by_alias=by_alias, - include=include, - exclude=exclude, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - ) - - def json( - self, - *, - include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - by_alias: bool = False, - skip_defaults: bool = None, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - encoder: Optional[Callable[[Any], Any]] = None, - **dumps_kwargs: Any, - ) -> str: - """ - Generate a JSON representation of the model, `include` and `exclude` arguments as per `dict()`. - - `encoder` is an optional function to supply as `default` to json.dumps(), other arguments as per `json.dumps()`. - """ - if skip_defaults is not None: - warnings.warn( - f'{self.__class__.__name__}.json(): "skip_defaults" is deprecated and replaced by "exclude_unset"', - DeprecationWarning, - ) - exclude_unset = skip_defaults - encoder = cast(Callable[[Any], Any], encoder or self.__json_encoder__) - data = self.dict( - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - if self.__custom_root_type__: - data = data[ROOT_KEY] - return self.__config__.json_dumps(data, default=encoder, **dumps_kwargs) - - @classmethod - def parse_obj(cls: Type['Model'], obj: Any) -> 'Model': - if cls.__custom_root_type__ and ( - not (isinstance(obj, dict) and obj.keys() == {ROOT_KEY}) or cls.__fields__[ROOT_KEY].shape == SHAPE_MAPPING - ): - obj = {ROOT_KEY: obj} - elif not isinstance(obj, dict): - try: - obj = dict(obj) - except (TypeError, ValueError) as e: - exc = TypeError(f'{cls.__name__} expected dict not {obj.__class__.__name__}') - raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls) from e - return cls(**obj) - - @classmethod - def parse_raw( - cls: Type['Model'], - b: StrBytes, - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - ) -> 'Model': - try: - obj = load_str_bytes( - b, - proto=proto, - content_type=content_type, - encoding=encoding, - allow_pickle=allow_pickle, - json_loads=cls.__config__.json_loads, - ) - except (ValueError, TypeError, UnicodeDecodeError) as e: - raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)], cls) - return cls.parse_obj(obj) - - @classmethod - def parse_file( - cls: Type['Model'], - path: Union[str, Path], - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - ) -> 'Model': - obj = load_file( - path, - proto=proto, - content_type=content_type, - encoding=encoding, - allow_pickle=allow_pickle, - json_loads=cls.__config__.json_loads, - ) - return cls.parse_obj(obj) - - @classmethod - def from_orm(cls: Type['Model'], obj: Any) -> 'Model': - if not cls.__config__.orm_mode: - raise ConfigError('You must have the config attribute orm_mode=True to use from_orm') - obj = cls._decompose_class(obj) - m = cls.__new__(cls) - values, fields_set, validation_error = validate_model(cls, obj) - if validation_error: - raise validation_error - object_setattr(m, '__dict__', values) - object_setattr(m, '__fields_set__', fields_set) - m._init_private_attributes() - return m - - @classmethod - def construct(cls: Type['Model'], _fields_set: Optional['SetStr'] = None, **values: Any) -> 'Model': - """ - Creates a new model setting __dict__ and __fields_set__ from trusted or pre-validated data. - Default values are respected, but no other validation is performed. - """ - m = cls.__new__(cls) - # default field values - fields_values = {name: field.get_default() for name, field in cls.__fields__.items() if not field.required} - fields_values.update(values) - object_setattr(m, '__dict__', fields_values) - if _fields_set is None: - _fields_set = set(values.keys()) - object_setattr(m, '__fields_set__', _fields_set) - m._init_private_attributes() - return m - - def copy( - self: 'Model', - *, - include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - update: 'DictStrAny' = None, - deep: bool = False, - ) -> 'Model': - """ - Duplicate a model, optionally choose which fields to include, exclude and change. - - :param include: fields to include in new model - :param exclude: fields to exclude from new model, as with values this takes precedence over include - :param update: values to change/add in the new model. Note: the data is not validated before creating - the new model: you should trust this data - :param deep: set to `True` to make a deep copy of the model - :return: new model instance - """ - - v = dict( - self._iter(to_dict=False, by_alias=False, include=include, exclude=exclude, exclude_unset=False), - **(update or {}), - ) - - if deep: - # chances of having empty dict here are quite low for using smart_deepcopy - v = deepcopy(v) - - cls = self.__class__ - m = cls.__new__(cls) - object_setattr(m, '__dict__', v) - object_setattr(m, '__fields_set__', self.__fields_set__.copy()) - for name in self.__private_attributes__: - value = getattr(self, name, Undefined) - if value is not Undefined: - if deep: - value = deepcopy(value) - object_setattr(m, name, value) - - return m - - @classmethod - def schema(cls, by_alias: bool = True, ref_template: str = default_ref_template) -> 'DictStrAny': - cached = cls.__schema_cache__.get((by_alias, ref_template)) - if cached is not None: - return cached - s = model_schema(cls, by_alias=by_alias, ref_template=ref_template) - cls.__schema_cache__[(by_alias, ref_template)] = s - return s - - @classmethod - def schema_json( - cls, *, by_alias: bool = True, ref_template: str = default_ref_template, **dumps_kwargs: Any - ) -> str: - from .json import pydantic_encoder - - return cls.__config__.json_dumps( - cls.schema(by_alias=by_alias, ref_template=ref_template), default=pydantic_encoder, **dumps_kwargs - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls: Type['Model'], value: Any) -> 'Model': - if isinstance(value, dict): - return cls(**value) - elif isinstance(value, cls): - return value.copy() - elif cls.__config__.orm_mode: - return cls.from_orm(value) - elif cls.__custom_root_type__: - return cls.parse_obj(value) - else: - try: - value_as_dict = dict(value) - except (TypeError, ValueError) as e: - raise DictError() from e - return cls(**value_as_dict) - - @classmethod - def _decompose_class(cls: Type['Model'], obj: Any) -> GetterDict: - return cls.__config__.getter_dict(obj) - - @classmethod - @no_type_check - def _get_value( - cls, - v: Any, - to_dict: bool, - by_alias: bool, - include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']], - exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']], - exclude_unset: bool, - exclude_defaults: bool, - exclude_none: bool, - ) -> Any: - - if isinstance(v, BaseModel): - if to_dict: - v_dict = v.dict( - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - include=include, - exclude=exclude, - exclude_none=exclude_none, - ) - if '__root__' in v_dict: - return v_dict['__root__'] - return v_dict - else: - return v.copy(include=include, exclude=exclude) - - value_exclude = ValueItems(v, exclude) if exclude else None - value_include = ValueItems(v, include) if include else None - - if isinstance(v, dict): - return { - k_: cls._get_value( - v_, - to_dict=to_dict, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - include=value_include and value_include.for_element(k_), - exclude=value_exclude and value_exclude.for_element(k_), - exclude_none=exclude_none, - ) - for k_, v_ in v.items() - if (not value_exclude or not value_exclude.is_excluded(k_)) - and (not value_include or value_include.is_included(k_)) - } - - elif sequence_like(v): - return v.__class__( - cls._get_value( - v_, - to_dict=to_dict, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - include=value_include and value_include.for_element(i), - exclude=value_exclude and value_exclude.for_element(i), - exclude_none=exclude_none, - ) - for i, v_ in enumerate(v) - if (not value_exclude or not value_exclude.is_excluded(i)) - and (not value_include or value_include.is_included(i)) - ) - - elif isinstance(v, Enum) and getattr(cls.Config, 'use_enum_values', False): - return v.value - - else: - return v - - @classmethod - def update_forward_refs(cls, **localns: Any) -> None: - """ - Try to update ForwardRefs on fields based on this Model, globalns and localns. - """ - globalns = sys.modules[cls.__module__].__dict__.copy() - globalns.setdefault(cls.__name__, cls) - for f in cls.__fields__.values(): - update_field_forward_refs(f, globalns=globalns, localns=localns) - - def __iter__(self) -> 'TupleGenerator': - """ - so `dict(model)` works - """ - yield from self.__dict__.items() - - def _iter( - self, - to_dict: bool = False, - by_alias: bool = False, - include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - ) -> 'TupleGenerator': - - allowed_keys = self._calculate_keys(include=include, exclude=exclude, exclude_unset=exclude_unset) - if allowed_keys is None and not (to_dict or by_alias or exclude_unset or exclude_defaults or exclude_none): - # huge boost for plain _iter() - yield from self.__dict__.items() - return - - value_exclude = ValueItems(self, exclude) if exclude else None - value_include = ValueItems(self, include) if include else None - - for field_key, v in self.__dict__.items(): - if ( - (allowed_keys is not None and field_key not in allowed_keys) - or (exclude_none and v is None) - or (exclude_defaults and getattr(self.__fields__.get(field_key), 'default', _missing) == v) - ): - continue - if by_alias and field_key in self.__fields__: - dict_key = self.__fields__[field_key].alias - else: - dict_key = field_key - if to_dict or value_include or value_exclude: - v = self._get_value( - v, - to_dict=to_dict, - by_alias=by_alias, - include=value_include and value_include.for_element(field_key), - exclude=value_exclude and value_exclude.for_element(field_key), - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - yield dict_key, v - - def _calculate_keys( - self, - include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']], - exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']], - exclude_unset: bool, - update: Optional['DictStrAny'] = None, - ) -> Optional[AbstractSet[str]]: - if include is None and exclude is None and exclude_unset is False: - return None - - keys: AbstractSet[str] - if exclude_unset: - keys = self.__fields_set__.copy() - else: - keys = self.__dict__.keys() - - if include is not None: - if isinstance(include, Mapping): - keys &= include.keys() - else: - keys &= include - - if update: - keys -= update.keys() - - if exclude: - if isinstance(exclude, Mapping): - keys -= {k for k, v in exclude.items() if v is ...} - else: - keys -= exclude - - return keys - - def __eq__(self, other: Any) -> bool: - if isinstance(other, BaseModel): - return self.dict() == other.dict() - else: - return self.dict() == other - - def __repr_args__(self) -> 'ReprArgs': - return self.__dict__.items() # type: ignore - - @property - def fields(self) -> Dict[str, ModelField]: - warnings.warn('`fields` attribute is deprecated, use `__fields__` instead', DeprecationWarning) - return self.__fields__ - - def to_string(self, pretty: bool = False) -> str: - warnings.warn('`model.to_string()` method is deprecated, use `str(model)` instead', DeprecationWarning) - return str(self) - - @property - def __values__(self) -> 'DictStrAny': - warnings.warn('`__values__` attribute is deprecated, use `__dict__` instead', DeprecationWarning) - return self.__dict__ - - -_is_base_model_class_defined = True - - -def create_model( - __model_name: str, - *, - __config__: Type[BaseConfig] = None, - __base__: Type[BaseModel] = None, - __module__: str = __name__, - __validators__: Dict[str, classmethod] = None, - **field_definitions: Any, -) -> Type[BaseModel]: - """ - Dynamically create a model. - :param __model_name: name of the created model - :param __config__: config class to use for the new model - :param __base__: base class for the new model to inherit from - :param __module__: module of the created model - :param __validators__: a dict of method names and @validator class methods - :param field_definitions: fields of the model (or extra fields if a base is supplied) - in the format `=(, )` or `=, e.g. - `foobar=(str, ...)` or `foobar=123`, or, for complex use-cases, in the format - `=`, e.g. `foo=Field(default_factory=datetime.utcnow, alias='bar')` - """ - if __base__: - if __config__ is not None: - raise ConfigError('to avoid confusion __config__ and __base__ cannot be used together') - else: - __base__ = BaseModel - - fields = {} - annotations = {} - - for f_name, f_def in field_definitions.items(): - if not is_valid_field(f_name): - warnings.warn(f'fields may not start with an underscore, ignoring "{f_name}"', RuntimeWarning) - if isinstance(f_def, tuple): - try: - f_annotation, f_value = f_def - except ValueError as e: - raise ConfigError( - 'field definitions should either be a tuple of (, ) or just a ' - 'default value, unfortunately this means tuples as ' - 'default values are not allowed' - ) from e - else: - f_annotation, f_value = None, f_def - - if f_annotation: - annotations[f_name] = f_annotation - fields[f_name] = f_value - - namespace: 'DictStrAny' = {'__annotations__': annotations, '__module__': __module__} - if __validators__: - namespace.update(__validators__) - namespace.update(fields) - if __config__: - namespace['Config'] = inherit_config(__config__, BaseConfig) - - return type(__model_name, (__base__,), namespace) - - -_missing = object() - - -def validate_model( # noqa: C901 (ignore complexity) - model: Type[BaseModel], input_data: 'DictStrAny', cls: 'ModelOrDc' = None -) -> Tuple['DictStrAny', 'SetStr', Optional[ValidationError]]: - """ - validate data against a model. - """ - values = {} - errors = [] - # input_data names, possibly alias - names_used = set() - # field names, never aliases - fields_set = set() - config = model.__config__ - check_extra = config.extra is not Extra.ignore - cls_ = cls or model - - for validator in model.__pre_root_validators__: - try: - input_data = validator(cls_, input_data) - except (ValueError, TypeError, AssertionError) as exc: - return {}, set(), ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls_) - - for name, field in model.__fields__.items(): - if field.type_.__class__ == ForwardRef: - raise ConfigError( - f'field "{field.name}" not yet prepared so type is still a ForwardRef, ' - f'you might need to call {cls_.__name__}.update_forward_refs().' - ) - - value = input_data.get(field.alias, _missing) - using_name = False - if value is _missing and config.allow_population_by_field_name and field.alt_alias: - value = input_data.get(field.name, _missing) - using_name = True - - if value is _missing: - if field.required: - errors.append(ErrorWrapper(MissingError(), loc=field.alias)) - continue - - value = field.get_default() - - if not config.validate_all and not field.validate_always: - values[name] = value - continue - else: - fields_set.add(name) - if check_extra: - names_used.add(field.name if using_name else field.alias) - - v_, errors_ = field.validate(value, values, loc=field.alias, cls=cls_) - if isinstance(errors_, ErrorWrapper): - errors.append(errors_) - elif isinstance(errors_, list): - errors.extend(errors_) - else: - values[name] = v_ - - if check_extra: - if isinstance(input_data, GetterDict): - extra = input_data.extra_keys() - names_used - else: - extra = input_data.keys() - names_used - if extra: - fields_set |= extra - if config.extra is Extra.allow: - for f in extra: - values[f] = input_data[f] - else: - for f in sorted(extra): - errors.append(ErrorWrapper(ExtraError(), loc=f)) - - for skip_on_failure, validator in model.__post_root_validators__: - if skip_on_failure and errors: - continue - try: - values = validator(cls_, values) - except (ValueError, TypeError, AssertionError) as exc: - errors.append(ErrorWrapper(exc, loc=ROOT_KEY)) - - if errors: - return values, fields_set, ValidationError(errors, cls_) - else: - return values, fields_set, None diff --git a/env/lib/python3.8/site-packages/pydantic/mypy.py b/env/lib/python3.8/site-packages/pydantic/mypy.py deleted file mode 100644 index 18d7ef09..00000000 --- a/env/lib/python3.8/site-packages/pydantic/mypy.py +++ /dev/null @@ -1,687 +0,0 @@ -from configparser import ConfigParser -from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type as TypingType, Union - -from mypy.errorcodes import ErrorCode -from mypy.nodes import ( - ARG_NAMED, - ARG_NAMED_OPT, - ARG_OPT, - ARG_POS, - ARG_STAR2, - MDEF, - Argument, - AssignmentStmt, - Block, - CallExpr, - ClassDef, - Context, - Decorator, - EllipsisExpr, - FuncBase, - FuncDef, - JsonDict, - MemberExpr, - NameExpr, - PassStmt, - PlaceholderNode, - RefExpr, - StrExpr, - SymbolNode, - SymbolTableNode, - TempNode, - TypeInfo, - TypeVarExpr, - Var, -) -from mypy.options import Options -from mypy.plugin import CheckerPluginInterface, ClassDefContext, MethodContext, Plugin, SemanticAnalyzerPluginInterface -from mypy.plugins import dataclasses -from mypy.semanal import set_callable_name # type: ignore -from mypy.server.trigger import make_wildcard_trigger -from mypy.types import ( - AnyType, - CallableType, - Instance, - NoneType, - Type, - TypeOfAny, - TypeType, - TypeVarDef, - TypeVarType, - UnionType, - get_proper_type, -) -from mypy.typevars import fill_typevars -from mypy.util import get_unique_redefinition_name - -CONFIGFILE_KEY = 'pydantic-mypy' -METADATA_KEY = 'pydantic-mypy-metadata' -BASEMODEL_FULLNAME = 'pydantic.main.BaseModel' -BASESETTINGS_FULLNAME = 'pydantic.env_settings.BaseSettings' -FIELD_FULLNAME = 'pydantic.fields.Field' -DATACLASS_FULLNAME = 'pydantic.dataclasses.dataclass' - - -def plugin(version: str) -> 'TypingType[Plugin]': - """ - `version` is the mypy version string - - We might want to use this to print a warning if the mypy version being used is - newer, or especially older, than we expect (or need). - """ - return PydanticPlugin - - -class PydanticPlugin(Plugin): - def __init__(self, options: Options) -> None: - self.plugin_config = PydanticPluginConfig(options) - super().__init__(options) - - def get_base_class_hook(self, fullname: str) -> 'Optional[Callable[[ClassDefContext], None]]': - sym = self.lookup_fully_qualified(fullname) - if sym and isinstance(sym.node, TypeInfo): # pragma: no branch - # No branching may occur if the mypy cache has not been cleared - if any(get_fullname(base) == BASEMODEL_FULLNAME for base in sym.node.mro): - return self._pydantic_model_class_maker_callback - return None - - def get_method_hook(self, fullname: str) -> Optional[Callable[[MethodContext], Type]]: - if fullname.endswith('.from_orm'): - return from_orm_callback - return None - - def get_class_decorator_hook(self, fullname: str) -> Optional[Callable[[ClassDefContext], None]]: - if fullname == DATACLASS_FULLNAME: - return dataclasses.dataclass_class_maker_callback - return None - - def _pydantic_model_class_maker_callback(self, ctx: ClassDefContext) -> None: - transformer = PydanticModelTransformer(ctx, self.plugin_config) - transformer.transform() - - -class PydanticPluginConfig: - __slots__ = ('init_forbid_extra', 'init_typed', 'warn_required_dynamic_aliases', 'warn_untyped_fields') - init_forbid_extra: bool - init_typed: bool - warn_required_dynamic_aliases: bool - warn_untyped_fields: bool - - def __init__(self, options: Options) -> None: - if options.config_file is None: # pragma: no cover - return - plugin_config = ConfigParser() - plugin_config.read(options.config_file) - for key in self.__slots__: - setting = plugin_config.getboolean(CONFIGFILE_KEY, key, fallback=False) - setattr(self, key, setting) - - -def from_orm_callback(ctx: MethodContext) -> Type: - """ - Raise an error if orm_mode is not enabled - """ - model_type: Instance - if isinstance(ctx.type, CallableType) and isinstance(ctx.type.ret_type, Instance): - model_type = ctx.type.ret_type # called on the class - elif isinstance(ctx.type, Instance): - model_type = ctx.type # called on an instance (unusual, but still valid) - else: # pragma: no cover - detail = f'ctx.type: {ctx.type} (of type {ctx.type.__class__.__name__})' - error_unexpected_behavior(detail, ctx.api, ctx.context) - return ctx.default_return_type - pydantic_metadata = model_type.type.metadata.get(METADATA_KEY) - if pydantic_metadata is None: - return ctx.default_return_type - orm_mode = pydantic_metadata.get('config', {}).get('orm_mode') - if orm_mode is not True: - error_from_orm(get_name(model_type.type), ctx.api, ctx.context) - return ctx.default_return_type - - -class PydanticModelTransformer: - tracked_config_fields: Set[str] = { - 'extra', - 'allow_mutation', - 'orm_mode', - 'allow_population_by_field_name', - 'alias_generator', - } - - def __init__(self, ctx: ClassDefContext, plugin_config: PydanticPluginConfig) -> None: - self._ctx = ctx - self.plugin_config = plugin_config - - def transform(self) -> None: - """ - Configures the BaseModel subclass according to the plugin settings. - - In particular: - * determines the model config and fields, - * adds a fields-aware signature for the initializer and construct methods - * freezes the class if allow_mutation = False - * stores the fields, config, and if the class is settings in the mypy metadata for access by subclasses - """ - ctx = self._ctx - info = self._ctx.cls.info - - config = self.collect_config() - fields = self.collect_fields(config) - for field in fields: - if info[field.name].type is None: - if not ctx.api.final_iteration: - ctx.api.defer() - is_settings = any(get_fullname(base) == BASESETTINGS_FULLNAME for base in info.mro[:-1]) - self.add_initializer(fields, config, is_settings) - self.add_construct_method(fields) - self.set_frozen(fields, frozen=config.allow_mutation is False) - info.metadata[METADATA_KEY] = { - 'fields': {field.name: field.serialize() for field in fields}, - 'config': config.set_values_dict(), - } - - def collect_config(self) -> 'ModelConfigData': - """ - Collects the values of the config attributes that are used by the plugin, accounting for parent classes. - """ - ctx = self._ctx - cls = ctx.cls - config = ModelConfigData() - for stmt in cls.defs.body: - if not isinstance(stmt, ClassDef): - continue - if stmt.name == 'Config': - for substmt in stmt.defs.body: - if not isinstance(substmt, AssignmentStmt): - continue - config.update(self.get_config_update(substmt)) - if ( - config.has_alias_generator - and not config.allow_population_by_field_name - and self.plugin_config.warn_required_dynamic_aliases - ): - error_required_dynamic_aliases(ctx.api, stmt) - for info in cls.info.mro[1:]: # 0 is the current class - if METADATA_KEY not in info.metadata: - continue - - # Each class depends on the set of fields in its ancestors - ctx.api.add_plugin_dependency(make_wildcard_trigger(get_fullname(info))) - for name, value in info.metadata[METADATA_KEY]['config'].items(): - config.setdefault(name, value) - return config - - def collect_fields(self, model_config: 'ModelConfigData') -> List['PydanticModelField']: - """ - Collects the fields for the model, accounting for parent classes - """ - # First, collect fields belonging to the current class. - ctx = self._ctx - cls = self._ctx.cls - fields = [] # type: List[PydanticModelField] - known_fields = set() # type: Set[str] - for stmt in cls.defs.body: - if not isinstance(stmt, AssignmentStmt): # `and stmt.new_syntax` to require annotation - continue - - lhs = stmt.lvalues[0] - if not isinstance(lhs, NameExpr): - continue - - if not stmt.new_syntax and self.plugin_config.warn_untyped_fields: - error_untyped_fields(ctx.api, stmt) - - # if lhs.name == '__config__': # BaseConfig not well handled; I'm not sure why yet - # continue - - sym = cls.info.names.get(lhs.name) - if sym is None: # pragma: no cover - # This is likely due to a star import (see the dataclasses plugin for a more detailed explanation) - # This is the same logic used in the dataclasses plugin - continue - - node = sym.node - if isinstance(node, PlaceholderNode): # pragma: no cover - # See the PlaceholderNode docstring for more detail about how this can occur - # Basically, it is an edge case when dealing with complex import logic - # This is the same logic used in the dataclasses plugin - continue - if not isinstance(node, Var): - continue - - # x: ClassVar[int] is ignored by dataclasses. - if node.is_classvar: - continue - - is_required = self.get_is_required(cls, stmt, lhs) - alias, has_dynamic_alias = self.get_alias_info(stmt) - if ( - has_dynamic_alias - and not model_config.allow_population_by_field_name - and self.plugin_config.warn_required_dynamic_aliases - ): - error_required_dynamic_aliases(ctx.api, stmt) - fields.append( - PydanticModelField( - name=lhs.name, - is_required=is_required, - alias=alias, - has_dynamic_alias=has_dynamic_alias, - line=stmt.line, - column=stmt.column, - ) - ) - known_fields.add(lhs.name) - all_fields = fields.copy() - for info in cls.info.mro[1:]: # 0 is the current class, -2 is BaseModel, -1 is object - if METADATA_KEY not in info.metadata: - continue - - superclass_fields = [] - # Each class depends on the set of fields in its ancestors - ctx.api.add_plugin_dependency(make_wildcard_trigger(get_fullname(info))) - - for name, data in info.metadata[METADATA_KEY]['fields'].items(): - if name not in known_fields: - field = PydanticModelField.deserialize(info, data) - known_fields.add(name) - superclass_fields.append(field) - else: - (field,) = [a for a in all_fields if a.name == name] - all_fields.remove(field) - superclass_fields.append(field) - all_fields = superclass_fields + all_fields - return all_fields - - def add_initializer(self, fields: List['PydanticModelField'], config: 'ModelConfigData', is_settings: bool) -> None: - """ - Adds a fields-aware `__init__` method to the class. - - The added `__init__` will be annotated with types vs. all `Any` depending on the plugin settings. - """ - ctx = self._ctx - typed = self.plugin_config.init_typed - use_alias = config.allow_population_by_field_name is not True - force_all_optional = is_settings or bool( - config.has_alias_generator and not config.allow_population_by_field_name - ) - init_arguments = self.get_field_arguments( - fields, typed=typed, force_all_optional=force_all_optional, use_alias=use_alias - ) - if not self.should_init_forbid_extra(fields, config): - var = Var('kwargs') - init_arguments.append(Argument(var, AnyType(TypeOfAny.explicit), None, ARG_STAR2)) - add_method(ctx, '__init__', init_arguments, NoneType()) - - def add_construct_method(self, fields: List['PydanticModelField']) -> None: - """ - Adds a fully typed `construct` classmethod to the class. - - Similar to the fields-aware __init__ method, but always uses the field names (not aliases), - and does not treat settings fields as optional. - """ - ctx = self._ctx - set_str = ctx.api.named_type('__builtins__.set', [ctx.api.named_type('__builtins__.str')]) - optional_set_str = UnionType([set_str, NoneType()]) - fields_set_argument = Argument(Var('_fields_set', optional_set_str), optional_set_str, None, ARG_OPT) - construct_arguments = self.get_field_arguments(fields, typed=True, force_all_optional=False, use_alias=False) - construct_arguments = [fields_set_argument] + construct_arguments - - obj_type = ctx.api.named_type('__builtins__.object') - self_tvar_name = '_PydanticBaseModel' # Make sure it does not conflict with other names in the class - tvar_fullname = ctx.cls.fullname + '.' + self_tvar_name - tvd = TypeVarDef(self_tvar_name, tvar_fullname, -1, [], obj_type) - self_tvar_expr = TypeVarExpr(self_tvar_name, tvar_fullname, [], obj_type) - ctx.cls.info.names[self_tvar_name] = SymbolTableNode(MDEF, self_tvar_expr) - self_type = TypeVarType(tvd) - add_method( - ctx, - 'construct', - construct_arguments, - return_type=self_type, - self_type=self_type, - tvar_def=tvd, - is_classmethod=True, - ) - - def set_frozen(self, fields: List['PydanticModelField'], frozen: bool) -> None: - """ - Marks all fields as properties so that attempts to set them trigger mypy errors. - - This is the same approach used by the attrs and dataclasses plugins. - """ - info = self._ctx.cls.info - for field in fields: - sym_node = info.names.get(field.name) - if sym_node is not None: - var = sym_node.node - assert isinstance(var, Var) - var.is_property = frozen - else: - var = field.to_var(info, use_alias=False) - var.info = info - var.is_property = frozen - var._fullname = get_fullname(info) + '.' + get_name(var) - info.names[get_name(var)] = SymbolTableNode(MDEF, var) - - def get_config_update(self, substmt: AssignmentStmt) -> Optional['ModelConfigData']: - """ - Determines the config update due to a single statement in the Config class definition. - - Warns if a tracked config attribute is set to a value the plugin doesn't know how to interpret (e.g., an int) - """ - lhs = substmt.lvalues[0] - if not (isinstance(lhs, NameExpr) and lhs.name in self.tracked_config_fields): - return None - if lhs.name == 'extra': - if isinstance(substmt.rvalue, StrExpr): - forbid_extra = substmt.rvalue.value == 'forbid' - elif isinstance(substmt.rvalue, MemberExpr): - forbid_extra = substmt.rvalue.name == 'forbid' - else: - error_invalid_config_value(lhs.name, self._ctx.api, substmt) - return None - return ModelConfigData(forbid_extra=forbid_extra) - if lhs.name == 'alias_generator': - has_alias_generator = True - if isinstance(substmt.rvalue, NameExpr) and substmt.rvalue.fullname == 'builtins.None': - has_alias_generator = False - return ModelConfigData(has_alias_generator=has_alias_generator) - if isinstance(substmt.rvalue, NameExpr) and substmt.rvalue.fullname in ('builtins.True', 'builtins.False'): - return ModelConfigData(**{lhs.name: substmt.rvalue.fullname == 'builtins.True'}) - error_invalid_config_value(lhs.name, self._ctx.api, substmt) - return None - - @staticmethod - def get_is_required(cls: ClassDef, stmt: AssignmentStmt, lhs: NameExpr) -> bool: - """ - Returns a boolean indicating whether the field defined in `stmt` is a required field. - """ - expr = stmt.rvalue - if isinstance(expr, TempNode): - # TempNode means annotation-only, so only non-required if Optional - value_type = get_proper_type(cls.info[lhs.name].type) - if isinstance(value_type, UnionType) and any(isinstance(item, NoneType) for item in value_type.items): - # Annotated as Optional, or otherwise having NoneType in the union - return False - return True - if isinstance(expr, CallExpr) and isinstance(expr.callee, RefExpr) and expr.callee.fullname == FIELD_FULLNAME: - # The "default value" is a call to `Field`; at this point, the field is - # only required if default is Ellipsis (i.e., `field_name: Annotation = Field(...)`) - return len(expr.args) > 0 and expr.args[0].__class__ is EllipsisExpr - # Only required if the "default value" is Ellipsis (i.e., `field_name: Annotation = ...`) - return isinstance(expr, EllipsisExpr) - - @staticmethod - def get_alias_info(stmt: AssignmentStmt) -> Tuple[Optional[str], bool]: - """ - Returns a pair (alias, has_dynamic_alias), extracted from the declaration of the field defined in `stmt`. - - `has_dynamic_alias` is True if and only if an alias is provided, but not as a string literal. - If `has_dynamic_alias` is True, `alias` will be None. - """ - expr = stmt.rvalue - if isinstance(expr, TempNode): - # TempNode means annotation-only - return None, False - - if not ( - isinstance(expr, CallExpr) and isinstance(expr.callee, RefExpr) and expr.callee.fullname == FIELD_FULLNAME - ): - # Assigned value is not a call to pydantic.fields.Field - return None, False - - for i, arg_name in enumerate(expr.arg_names): - if arg_name != 'alias': - continue - arg = expr.args[i] - if isinstance(arg, StrExpr): - return arg.value, False - else: - return None, True - return None, False - - def get_field_arguments( - self, fields: List['PydanticModelField'], typed: bool, force_all_optional: bool, use_alias: bool - ) -> List[Argument]: - """ - Helper function used during the construction of the `__init__` and `construct` method signatures. - - Returns a list of mypy Argument instances for use in the generated signatures. - """ - info = self._ctx.cls.info - arguments = [ - field.to_argument(info, typed=typed, force_optional=force_all_optional, use_alias=use_alias) - for field in fields - if not (use_alias and field.has_dynamic_alias) - ] - return arguments - - def should_init_forbid_extra(self, fields: List['PydanticModelField'], config: 'ModelConfigData') -> bool: - """ - Indicates whether the generated `__init__` should get a `**kwargs` at the end of its signature - - We disallow arbitrary kwargs if the extra config setting is "forbid", or if the plugin config says to, - *unless* a required dynamic alias is present (since then we can't determine a valid signature). - """ - if not config.allow_population_by_field_name: - if self.is_dynamic_alias_present(fields, bool(config.has_alias_generator)): - return False - if config.forbid_extra: - return True - return self.plugin_config.init_forbid_extra - - @staticmethod - def is_dynamic_alias_present(fields: List['PydanticModelField'], has_alias_generator: bool) -> bool: - """ - Returns whether any fields on the model have a "dynamic alias", i.e., an alias that cannot be - determined during static analysis. - """ - for field in fields: - if field.has_dynamic_alias: - return True - if has_alias_generator: - for field in fields: - if field.alias is None: - return True - return False - - -class PydanticModelField: - def __init__( - self, name: str, is_required: bool, alias: Optional[str], has_dynamic_alias: bool, line: int, column: int - ): - self.name = name - self.is_required = is_required - self.alias = alias - self.has_dynamic_alias = has_dynamic_alias - self.line = line - self.column = column - - def to_var(self, info: TypeInfo, use_alias: bool) -> Var: - name = self.name - if use_alias and self.alias is not None: - name = self.alias - return Var(name, info[self.name].type) - - def to_argument(self, info: TypeInfo, typed: bool, force_optional: bool, use_alias: bool) -> Argument: - if typed and info[self.name].type is not None: - type_annotation = info[self.name].type - else: - type_annotation = AnyType(TypeOfAny.explicit) - return Argument( - variable=self.to_var(info, use_alias), - type_annotation=type_annotation, - initializer=None, - kind=ARG_NAMED_OPT if force_optional or not self.is_required else ARG_NAMED, - ) - - def serialize(self) -> JsonDict: - return self.__dict__ - - @classmethod - def deserialize(cls, info: TypeInfo, data: JsonDict) -> 'PydanticModelField': - return cls(**data) - - -class ModelConfigData: - def __init__( - self, - forbid_extra: Optional[bool] = None, - allow_mutation: Optional[bool] = None, - orm_mode: Optional[bool] = None, - allow_population_by_field_name: Optional[bool] = None, - has_alias_generator: Optional[bool] = None, - ): - self.forbid_extra = forbid_extra - self.allow_mutation = allow_mutation - self.orm_mode = orm_mode - self.allow_population_by_field_name = allow_population_by_field_name - self.has_alias_generator = has_alias_generator - - def set_values_dict(self) -> Dict[str, Any]: - return {k: v for k, v in self.__dict__.items() if v is not None} - - def update(self, config: Optional['ModelConfigData']) -> None: - if config is None: - return - for k, v in config.set_values_dict().items(): - setattr(self, k, v) - - def setdefault(self, key: str, value: Any) -> None: - if getattr(self, key) is None: - setattr(self, key, value) - - -ERROR_ORM = ErrorCode('pydantic-orm', 'Invalid from_orm call', 'Pydantic') -ERROR_CONFIG = ErrorCode('pydantic-config', 'Invalid config value', 'Pydantic') -ERROR_ALIAS = ErrorCode('pydantic-alias', 'Dynamic alias disallowed', 'Pydantic') -ERROR_UNEXPECTED = ErrorCode('pydantic-unexpected', 'Unexpected behavior', 'Pydantic') -ERROR_UNTYPED = ErrorCode('pydantic-field', 'Untyped field disallowed', 'Pydantic') - - -def error_from_orm(model_name: str, api: CheckerPluginInterface, context: Context) -> None: - api.fail(f'"{model_name}" does not have orm_mode=True', context, code=ERROR_ORM) - - -def error_invalid_config_value(name: str, api: SemanticAnalyzerPluginInterface, context: Context) -> None: - api.fail(f'Invalid value for "Config.{name}"', context, code=ERROR_CONFIG) - - -def error_required_dynamic_aliases(api: SemanticAnalyzerPluginInterface, context: Context) -> None: - api.fail('Required dynamic aliases disallowed', context, code=ERROR_ALIAS) - - -def error_unexpected_behavior(detail: str, api: CheckerPluginInterface, context: Context) -> None: # pragma: no cover - # Can't think of a good way to test this, but I confirmed it renders as desired by adding to a non-error path - link = 'https://github.com/samuelcolvin/pydantic/issues/new/choose' - full_message = f'The pydantic mypy plugin ran into unexpected behavior: {detail}\n' - full_message += f'Please consider reporting this bug at {link} so we can try to fix it!' - api.fail(full_message, context, code=ERROR_UNEXPECTED) - - -def error_untyped_fields(api: SemanticAnalyzerPluginInterface, context: Context) -> None: - api.fail('Untyped fields disallowed', context, code=ERROR_UNTYPED) - - -def add_method( - ctx: ClassDefContext, - name: str, - args: List[Argument], - return_type: Type, - self_type: Optional[Type] = None, - tvar_def: Optional[TypeVarDef] = None, - is_classmethod: bool = False, - is_new: bool = False, - # is_staticmethod: bool = False, -) -> None: - """ - Adds a new method to a class. - - This can be dropped if/when https://github.com/python/mypy/issues/7301 is merged - """ - info = ctx.cls.info - - # First remove any previously generated methods with the same name - # to avoid clashes and problems in the semantic analyzer. - if name in info.names: - sym = info.names[name] - if sym.plugin_generated and isinstance(sym.node, FuncDef): - ctx.cls.defs.body.remove(sym.node) - - self_type = self_type or fill_typevars(info) - if is_classmethod or is_new: - first = [Argument(Var('_cls'), TypeType.make_normalized(self_type), None, ARG_POS)] - # elif is_staticmethod: - # first = [] - else: - self_type = self_type or fill_typevars(info) - first = [Argument(Var('self'), self_type, None, ARG_POS)] - args = first + args - arg_types, arg_names, arg_kinds = [], [], [] - for arg in args: - assert arg.type_annotation, 'All arguments must be fully typed.' - arg_types.append(arg.type_annotation) - arg_names.append(get_name(arg.variable)) - arg_kinds.append(arg.kind) - - function_type = ctx.api.named_type('__builtins__.function') - signature = CallableType(arg_types, arg_kinds, arg_names, return_type, function_type) - if tvar_def: - signature.variables = [tvar_def] - - func = FuncDef(name, args, Block([PassStmt()])) - func.info = info - func.type = set_callable_name(signature, func) - func.is_class = is_classmethod - # func.is_static = is_staticmethod - func._fullname = get_fullname(info) + '.' + name - func.line = info.line - - # NOTE: we would like the plugin generated node to dominate, but we still - # need to keep any existing definitions so they get semantically analyzed. - if name in info.names: - # Get a nice unique name instead. - r_name = get_unique_redefinition_name(name, info.names) - info.names[r_name] = info.names[name] - - if is_classmethod: # or is_staticmethod: - func.is_decorated = True - v = Var(name, func.type) - v.info = info - v._fullname = func._fullname - # if is_classmethod: - v.is_classmethod = True - dec = Decorator(func, [NameExpr('classmethod')], v) - # else: - # v.is_staticmethod = True - # dec = Decorator(func, [NameExpr('staticmethod')], v) - - dec.line = info.line - sym = SymbolTableNode(MDEF, dec) - else: - sym = SymbolTableNode(MDEF, func) - sym.plugin_generated = True - - info.names[name] = sym - info.defn.defs.body.append(func) - - -def get_fullname(x: Union[FuncBase, SymbolNode]) -> str: - """ - Used for compatibility with mypy 0.740; can be dropped once support for 0.740 is dropped. - """ - fn = x.fullname - if callable(fn): # pragma: no cover - return fn() - return fn - - -def get_name(x: Union[FuncBase, SymbolNode]) -> str: - """ - Used for compatibility with mypy 0.740; can be dropped once support for 0.740 is dropped. - """ - fn = x.name - if callable(fn): # pragma: no cover - return fn() - return fn diff --git a/env/lib/python3.8/site-packages/pydantic/networks.py b/env/lib/python3.8/site-packages/pydantic/networks.py deleted file mode 100644 index 2418e5b6..00000000 --- a/env/lib/python3.8/site-packages/pydantic/networks.py +++ /dev/null @@ -1,462 +0,0 @@ -import re -from ipaddress import ( - IPv4Address, - IPv4Interface, - IPv4Network, - IPv6Address, - IPv6Interface, - IPv6Network, - _BaseAddress, - _BaseNetwork, -) -from typing import TYPE_CHECKING, Any, Dict, Generator, Optional, Pattern, Set, Tuple, Type, Union, cast, no_type_check - -from . import errors -from .utils import Representation, update_not_none -from .validators import constr_length_validator, str_validator - -if TYPE_CHECKING: - import email_validator - - from .fields import ModelField - from .main import BaseConfig # noqa: F401 - from .typing import AnyCallable - - CallableGenerator = Generator[AnyCallable, None, None] -else: - email_validator = None - -NetworkType = Union[str, bytes, int, Tuple[Union[str, bytes, int], Union[str, int]]] - -__all__ = [ - 'AnyUrl', - 'AnyHttpUrl', - 'HttpUrl', - 'stricturl', - 'EmailStr', - 'NameEmail', - 'IPvAnyAddress', - 'IPvAnyInterface', - 'IPvAnyNetwork', - 'PostgresDsn', - 'RedisDsn', - 'validate_email', -] - - -_url_regex_cache = None -_ascii_domain_regex_cache = None -_int_domain_regex_cache = None - - -def url_regex() -> Pattern[str]: - global _url_regex_cache - if _url_regex_cache is None: - _url_regex_cache = re.compile( - r'(?:(?P[a-z][a-z0-9+\-.]+)://)?' # scheme https://tools.ietf.org/html/rfc3986#appendix-A - r'(?:(?P[^\s:/]+)(?::(?P[^\s/]*))?@)?' # user info - r'(?:' - r'(?P(?:\d{1,3}\.){3}\d{1,3})|' # ipv4 - r'(?P\[[A-F0-9]*:[A-F0-9:]+\])|' # ipv6 - r'(?P[^\s/:?#]+)' # domain, validation occurs later - r')?' - r'(?::(?P\d+))?' # port - r'(?P/[^\s?]*)?' # path - r'(?:\?(?P[^\s#]+))?' # query - r'(?:#(?P\S+))?', # fragment - re.IGNORECASE, - ) - return _url_regex_cache - - -def ascii_domain_regex() -> Pattern[str]: - global _ascii_domain_regex_cache - if _ascii_domain_regex_cache is None: - ascii_chunk = r'[_0-9a-z](?:[-_0-9a-z]{0,61}[_0-9a-z])?' - ascii_domain_ending = r'(?P\.[a-z]{2,63})?\.?' - _ascii_domain_regex_cache = re.compile( - fr'(?:{ascii_chunk}\.)*?{ascii_chunk}{ascii_domain_ending}', re.IGNORECASE - ) - return _ascii_domain_regex_cache - - -def int_domain_regex() -> Pattern[str]: - global _int_domain_regex_cache - if _int_domain_regex_cache is None: - int_chunk = r'[_0-9a-\U00040000](?:[-_0-9a-\U00040000]{0,61}[_0-9a-\U00040000])?' - int_domain_ending = r'(?P(\.[^\W\d_]{2,63})|(\.(?:xn--)[_0-9a-z-]{2,63}))?\.?' - _int_domain_regex_cache = re.compile(fr'(?:{int_chunk}\.)*?{int_chunk}{int_domain_ending}', re.IGNORECASE) - return _int_domain_regex_cache - - -class AnyUrl(str): - strip_whitespace = True - min_length = 1 - max_length = 2 ** 16 - allowed_schemes: Optional[Set[str]] = None - tld_required: bool = False - user_required: bool = False - - __slots__ = ('scheme', 'user', 'password', 'host', 'tld', 'host_type', 'port', 'path', 'query', 'fragment') - - @no_type_check - def __new__(cls, url: Optional[str], **kwargs) -> object: - return str.__new__(cls, cls.build(**kwargs) if url is None else url) - - def __init__( - self, - url: str, - *, - scheme: str, - user: Optional[str] = None, - password: Optional[str] = None, - host: str, - tld: Optional[str] = None, - host_type: str = 'domain', - port: Optional[str] = None, - path: Optional[str] = None, - query: Optional[str] = None, - fragment: Optional[str] = None, - ) -> None: - str.__init__(url) - self.scheme = scheme - self.user = user - self.password = password - self.host = host - self.tld = tld - self.host_type = host_type - self.port = port - self.path = path - self.query = query - self.fragment = fragment - - @classmethod - def build( - cls, - *, - scheme: str, - user: Optional[str] = None, - password: Optional[str] = None, - host: str, - port: Optional[str] = None, - path: Optional[str] = None, - query: Optional[str] = None, - fragment: Optional[str] = None, - **kwargs: str, - ) -> str: - url = scheme + '://' - if user: - url += user - if password: - url += ':' + password - url += '@' - url += host - if port: - url += ':' + port - if path: - url += path - if query: - url += '?' + query - if fragment: - url += '#' + fragment - return url - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none(field_schema, minLength=cls.min_length, maxLength=cls.max_length, format='uri') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: Any, field: 'ModelField', config: 'BaseConfig') -> 'AnyUrl': - if value.__class__ == cls: - return value - value = str_validator(value) - if cls.strip_whitespace: - value = value.strip() - url: str = cast(str, constr_length_validator(value, field, config)) - - m = url_regex().match(url) - # the regex should always match, if it doesn't please report with details of the URL tried - assert m, 'URL regex failed unexpectedly' - - parts = m.groupdict() - scheme = parts['scheme'] - if scheme is None: - raise errors.UrlSchemeError() - - if cls.allowed_schemes and scheme.lower() not in cls.allowed_schemes: - raise errors.UrlSchemePermittedError(cls.allowed_schemes) - - port = parts['port'] - if port is not None and int(port) > 65_535: - raise errors.UrlPortError() - - user = parts['user'] - if cls.user_required and user is None: - raise errors.UrlUserInfoError() - - host, tld, host_type, rebuild = cls.validate_host(parts) - - if m.end() != len(url): - raise errors.UrlExtraError(extra=url[m.end() :]) - - return cls( - None if rebuild else url, - scheme=scheme, - user=user, - password=parts['password'], - host=host, - tld=tld, - host_type=host_type, - port=port, - path=parts['path'], - query=parts['query'], - fragment=parts['fragment'], - ) - - @classmethod - def validate_host(cls, parts: Dict[str, str]) -> Tuple[str, Optional[str], str, bool]: - host, tld, host_type, rebuild = None, None, None, False - for f in ('domain', 'ipv4', 'ipv6'): - host = parts[f] - if host: - host_type = f - break - - if host is None: - raise errors.UrlHostError() - elif host_type == 'domain': - is_international = False - d = ascii_domain_regex().fullmatch(host) - if d is None: - d = int_domain_regex().fullmatch(host) - if d is None: - raise errors.UrlHostError() - is_international = True - - tld = d.group('tld') - if tld is None and not is_international: - d = int_domain_regex().fullmatch(host) - tld = d.group('tld') - is_international = True - - if tld is not None: - tld = tld[1:] - elif cls.tld_required: - raise errors.UrlHostTldError() - - if is_international: - host_type = 'int_domain' - rebuild = True - host = host.encode('idna').decode('ascii') - if tld is not None: - tld = tld.encode('idna').decode('ascii') - - return host, tld, host_type, rebuild # type: ignore - - def __repr__(self) -> str: - extra = ', '.join(f'{n}={getattr(self, n)!r}' for n in self.__slots__ if getattr(self, n) is not None) - return f'{self.__class__.__name__}({super().__repr__()}, {extra})' - - -class AnyHttpUrl(AnyUrl): - allowed_schemes = {'http', 'https'} - - -class HttpUrl(AnyUrl): - allowed_schemes = {'http', 'https'} - tld_required = True - # https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers - max_length = 2083 - - -class PostgresDsn(AnyUrl): - allowed_schemes = {'postgres', 'postgresql'} - user_required = True - - -class RedisDsn(AnyUrl): - allowed_schemes = {'redis'} - - -def stricturl( - *, - strip_whitespace: bool = True, - min_length: int = 1, - max_length: int = 2 ** 16, - tld_required: bool = True, - allowed_schemes: Optional[Set[str]] = None, -) -> Type[AnyUrl]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict( - strip_whitespace=strip_whitespace, - min_length=min_length, - max_length=max_length, - tld_required=tld_required, - allowed_schemes=allowed_schemes, - ) - return type('UrlValue', (AnyUrl,), namespace) - - -def import_email_validator() -> None: - global email_validator - try: - import email_validator - except ImportError as e: - raise ImportError('email-validator is not installed, run `pip install pydantic[email]`') from e - - -class EmailStr(str): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='email') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - # included here and below so the error happens straight away - import_email_validator() - - yield str_validator - yield cls.validate - - @classmethod - def validate(cls, value: Union[str]) -> str: - return validate_email(value)[1] - - -class NameEmail(Representation): - __slots__ = 'name', 'email' - - def __init__(self, name: str, email: str): - self.name = name - self.email = email - - def __eq__(self, other: Any) -> bool: - return isinstance(other, NameEmail) and (self.name, self.email) == (other.name, other.email) - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='name-email') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - import_email_validator() - - yield cls.validate - - @classmethod - def validate(cls, value: Any) -> 'NameEmail': - if value.__class__ == cls: - return value - value = str_validator(value) - return cls(*validate_email(value)) - - def __str__(self) -> str: - return f'{self.name} <{self.email}>' - - -class IPvAnyAddress(_BaseAddress): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='ipvanyaddress') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: Union[str, bytes, int]) -> Union[IPv4Address, IPv6Address]: - try: - return IPv4Address(value) - except ValueError: - pass - - try: - return IPv6Address(value) - except ValueError: - raise errors.IPvAnyAddressError() - - -class IPvAnyInterface(_BaseAddress): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='ipvanyinterface') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: NetworkType) -> Union[IPv4Interface, IPv6Interface]: - try: - return IPv4Interface(value) - except ValueError: - pass - - try: - return IPv6Interface(value) - except ValueError: - raise errors.IPvAnyInterfaceError() - - -class IPvAnyNetwork(_BaseNetwork): # type: ignore - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='ipvanynetwork') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: NetworkType) -> Union[IPv4Network, IPv6Network]: - # Assume IP Network is defined with a default value for ``strict`` argument. - # Define your own class if you want to specify network address check strictness. - try: - return IPv4Network(value) - except ValueError: - pass - - try: - return IPv6Network(value) - except ValueError: - raise errors.IPvAnyNetworkError() - - -pretty_email_regex = re.compile(r'([\w ]*?) *<(.*)> *') - - -def validate_email(value: Union[str]) -> Tuple[str, str]: - """ - Brutally simple email address validation. Note unlike most email address validation - * raw ip address (literal) domain parts are not allowed. - * "John Doe " style "pretty" email addresses are processed - * the local part check is extremely basic. This raises the possibility of unicode spoofing, but no better - solution is really possible. - * spaces are striped from the beginning and end of addresses but no error is raised - - See RFC 5322 but treat it with suspicion, there seems to exist no universally acknowledged test for a valid email! - """ - if email_validator is None: - import_email_validator() - - m = pretty_email_regex.fullmatch(value) - name: Optional[str] = None - if m: - name, value = m.groups() - - email = value.strip() - - try: - email_validator.validate_email(email, check_deliverability=False) - except email_validator.EmailNotValidError as e: - raise errors.EmailError() from e - - at_index = email.index('@') - local_part = email[:at_index] # RFC 5321, local part must be case-sensitive. - global_part = email[at_index:].lower() - - return name or local_part, local_part + global_part diff --git a/env/lib/python3.8/site-packages/pydantic/parse.py b/env/lib/python3.8/site-packages/pydantic/parse.py deleted file mode 100644 index 7ac330ca..00000000 --- a/env/lib/python3.8/site-packages/pydantic/parse.py +++ /dev/null @@ -1,66 +0,0 @@ -import json -import pickle -from enum import Enum -from pathlib import Path -from typing import Any, Callable, Union - -from .types import StrBytes - - -class Protocol(str, Enum): - json = 'json' - pickle = 'pickle' - - -def load_str_bytes( - b: StrBytes, - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - json_loads: Callable[[str], Any] = json.loads, -) -> Any: - if proto is None and content_type: - if content_type.endswith(('json', 'javascript')): - pass - elif allow_pickle and content_type.endswith('pickle'): - proto = Protocol.pickle - else: - raise TypeError(f'Unknown content-type: {content_type}') - - proto = proto or Protocol.json - - if proto == Protocol.json: - if isinstance(b, bytes): - b = b.decode(encoding) - return json_loads(b) - elif proto == Protocol.pickle: - if not allow_pickle: - raise RuntimeError('Trying to decode with pickle with allow_pickle=False') - bb = b if isinstance(b, bytes) else b.encode() - return pickle.loads(bb) - else: - raise TypeError(f'Unknown protocol: {proto}') - - -def load_file( - path: Union[str, Path], - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - json_loads: Callable[[str], Any] = json.loads, -) -> Any: - path = Path(path) - b = path.read_bytes() - if content_type is None: - if path.suffix in ('.js', '.json'): - proto = Protocol.json - elif path.suffix == '.pkl': - proto = Protocol.pickle - - return load_str_bytes( - b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle, json_loads=json_loads - ) diff --git a/env/lib/python3.8/site-packages/pydantic/py.typed b/env/lib/python3.8/site-packages/pydantic/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/pydantic/schema.py b/env/lib/python3.8/site-packages/pydantic/schema.py deleted file mode 100644 index a6a2777f..00000000 --- a/env/lib/python3.8/site-packages/pydantic/schema.py +++ /dev/null @@ -1,971 +0,0 @@ -import re -import warnings -from datetime import date, datetime, time, timedelta -from decimal import Decimal -from enum import Enum -from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network -from pathlib import Path -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Dict, - FrozenSet, - Iterable, - List, - Optional, - Pattern, - Sequence, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) -from uuid import UUID - -from .fields import ( - SHAPE_FROZENSET, - SHAPE_ITERABLE, - SHAPE_LIST, - SHAPE_MAPPING, - SHAPE_SEQUENCE, - SHAPE_SET, - SHAPE_SINGLETON, - SHAPE_TUPLE, - SHAPE_TUPLE_ELLIPSIS, - FieldInfo, - ModelField, -) -from .json import pydantic_encoder -from .networks import AnyUrl, EmailStr -from .types import ( - ConstrainedDecimal, - ConstrainedFloat, - ConstrainedInt, - ConstrainedList, - ConstrainedSet, - ConstrainedStr, - SecretBytes, - SecretStr, - conbytes, - condecimal, - confloat, - conint, - conlist, - conset, - constr, -) -from .typing import ForwardRef, Literal, get_args, get_origin, is_callable_type, is_literal_type, literal_values -from .utils import ROOT_KEY, get_model, lenient_issubclass, sequence_like - -if TYPE_CHECKING: - from .dataclasses import Dataclass # noqa: F401 - from .main import BaseModel # noqa: F401 - -default_prefix = '#/definitions/' -default_ref_template = '#/definitions/{model}' - -TypeModelOrEnum = Union[Type['BaseModel'], Type[Enum]] -TypeModelSet = Set[TypeModelOrEnum] - - -def schema( - models: Sequence[Union[Type['BaseModel'], Type['Dataclass']]], - *, - by_alias: bool = True, - title: Optional[str] = None, - description: Optional[str] = None, - ref_prefix: Optional[str] = None, - ref_template: str = default_ref_template, -) -> Dict[str, Any]: - """ - Process a list of models and generate a single JSON Schema with all of them defined in the ``definitions`` - top-level JSON key, including their sub-models. - - :param models: a list of models to include in the generated JSON Schema - :param by_alias: generate the schemas using the aliases defined, if any - :param title: title for the generated schema that includes the definitions - :param description: description for the generated schema - :param ref_prefix: the JSON Pointer prefix for schema references with ``$ref``, if None, will be set to the - default of ``#/definitions/``. Update it if you want the schemas to reference the definitions somewhere - else, e.g. for OpenAPI use ``#/components/schemas/``. The resulting generated schemas will still be at the - top-level key ``definitions``, so you can extract them from there. But all the references will have the set - prefix. - :param ref_template: Use a ``string.format()`` template for ``$ref`` instead of a prefix. This can be useful - for references that cannot be represented by ``ref_prefix`` such as a definition stored in another file. For - a sibling json file in a ``/schemas`` directory use ``"/schemas/${model}.json#"``. - :return: dict with the JSON Schema with a ``definitions`` top-level key including the schema definitions for - the models and sub-models passed in ``models``. - """ - clean_models = [get_model(model) for model in models] - flat_models = get_flat_models_from_models(clean_models) - model_name_map = get_model_name_map(flat_models) - definitions = {} - output_schema: Dict[str, Any] = {} - if title: - output_schema['title'] = title - if description: - output_schema['description'] = description - for model in clean_models: - m_schema, m_definitions, m_nested_models = model_process_schema( - model, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - ) - definitions.update(m_definitions) - model_name = model_name_map[model] - definitions[model_name] = m_schema - if definitions: - output_schema['definitions'] = definitions - return output_schema - - -def model_schema( - model: Union[Type['BaseModel'], Type['Dataclass']], - by_alias: bool = True, - ref_prefix: Optional[str] = None, - ref_template: str = default_ref_template, -) -> Dict[str, Any]: - """ - Generate a JSON Schema for one model. With all the sub-models defined in the ``definitions`` top-level - JSON key. - - :param model: a Pydantic model (a class that inherits from BaseModel) - :param by_alias: generate the schemas using the aliases defined, if any - :param ref_prefix: the JSON Pointer prefix for schema references with ``$ref``, if None, will be set to the - default of ``#/definitions/``. Update it if you want the schemas to reference the definitions somewhere - else, e.g. for OpenAPI use ``#/components/schemas/``. The resulting generated schemas will still be at the - top-level key ``definitions``, so you can extract them from there. But all the references will have the set - prefix. - :param ref_template: Use a ``string.format()`` template for ``$ref`` instead of a prefix. This can be useful for - references that cannot be represented by ``ref_prefix`` such as a definition stored in another file. For a - sibling json file in a ``/schemas`` directory use ``"/schemas/${model}.json#"``. - :return: dict with the JSON Schema for the passed ``model`` - """ - model = get_model(model) - flat_models = get_flat_models_from_model(model) - model_name_map = get_model_name_map(flat_models) - model_name = model_name_map[model] - m_schema, m_definitions, nested_models = model_process_schema( - model, by_alias=by_alias, model_name_map=model_name_map, ref_prefix=ref_prefix, ref_template=ref_template - ) - if model_name in nested_models: - # model_name is in Nested models, it has circular references - m_definitions[model_name] = m_schema - m_schema = get_schema_ref(model_name, ref_prefix, ref_template, False) - if m_definitions: - m_schema.update({'definitions': m_definitions}) - return m_schema - - -def get_field_info_schema(field: ModelField) -> Tuple[Dict[str, Any], bool]: - schema_overrides = False - - # If no title is explicitly set, we don't set title in the schema for enums. - # The behaviour is the same as `BaseModel` reference, where the default title - # is in the definitions part of the schema. - schema: Dict[str, Any] = {} - if field.field_info.title or not lenient_issubclass(field.type_, Enum): - schema['title'] = field.field_info.title or field.alias.title().replace('_', ' ') - - if field.field_info.title: - schema_overrides = True - - if field.field_info.description: - schema['description'] = field.field_info.description - schema_overrides = True - - if not field.required and not field.field_info.const and field.default is not None: - schema['default'] = encode_default(field.default) - schema_overrides = True - - return schema, schema_overrides - - -def field_schema( - field: ModelField, - *, - by_alias: bool = True, - model_name_map: Dict[TypeModelOrEnum, str], - ref_prefix: Optional[str] = None, - ref_template: str = default_ref_template, - known_models: TypeModelSet = None, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - Process a Pydantic field and return a tuple with a JSON Schema for it as the first item. - Also return a dictionary of definitions with models as keys and their schemas as values. If the passed field - is a model and has sub-models, and those sub-models don't have overrides (as ``title``, ``default``, etc), they - will be included in the definitions and referenced in the schema instead of included recursively. - - :param field: a Pydantic ``ModelField`` - :param by_alias: use the defined alias (if any) in the returned schema - :param model_name_map: used to generate the JSON Schema references to other models included in the definitions - :param ref_prefix: the JSON Pointer prefix to use for references to other schemas, if None, the default of - #/definitions/ will be used - :param ref_template: Use a ``string.format()`` template for ``$ref`` instead of a prefix. This can be useful for - references that cannot be represented by ``ref_prefix`` such as a definition stored in another file. For a - sibling json file in a ``/schemas`` directory use ``"/schemas/${model}.json#"``. - :param known_models: used to solve circular references - :return: tuple of the schema for this field and additional definitions - """ - s, schema_overrides = get_field_info_schema(field) - - validation_schema = get_field_schema_validations(field) - if validation_schema: - s.update(validation_schema) - schema_overrides = True - - f_schema, f_definitions, f_nested_models = field_type_schema( - field, - by_alias=by_alias, - model_name_map=model_name_map, - schema_overrides=schema_overrides, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models or set(), - ) - # $ref will only be returned when there are no schema_overrides - if '$ref' in f_schema: - return f_schema, f_definitions, f_nested_models - else: - s.update(f_schema) - return s, f_definitions, f_nested_models - - -numeric_types = (int, float, Decimal) -_str_types_attrs: Tuple[Tuple[str, Union[type, Tuple[type, ...]], str], ...] = ( - ('max_length', numeric_types, 'maxLength'), - ('min_length', numeric_types, 'minLength'), - ('regex', str, 'pattern'), -) - -_numeric_types_attrs: Tuple[Tuple[str, Union[type, Tuple[type, ...]], str], ...] = ( - ('gt', numeric_types, 'exclusiveMinimum'), - ('lt', numeric_types, 'exclusiveMaximum'), - ('ge', numeric_types, 'minimum'), - ('le', numeric_types, 'maximum'), - ('multiple_of', numeric_types, 'multipleOf'), -) - - -def get_field_schema_validations(field: ModelField) -> Dict[str, Any]: - """ - Get the JSON Schema validation keywords for a ``field`` with an annotation of - a Pydantic ``FieldInfo`` with validation arguments. - """ - f_schema: Dict[str, Any] = {} - - if lenient_issubclass(field.type_, Enum): - # schema is already updated by `enum_process_schema` - return f_schema - - if lenient_issubclass(field.type_, (str, bytes)): - for attr_name, t, keyword in _str_types_attrs: - attr = getattr(field.field_info, attr_name, None) - if isinstance(attr, t): - f_schema[keyword] = attr - if lenient_issubclass(field.type_, numeric_types) and not issubclass(field.type_, bool): - for attr_name, t, keyword in _numeric_types_attrs: - attr = getattr(field.field_info, attr_name, None) - if isinstance(attr, t): - f_schema[keyword] = attr - if field.field_info is not None and field.field_info.const: - f_schema['const'] = field.default - if field.field_info.extra: - f_schema.update(field.field_info.extra) - modify_schema = getattr(field.outer_type_, '__modify_schema__', None) - if modify_schema: - modify_schema(f_schema) - return f_schema - - -def get_model_name_map(unique_models: TypeModelSet) -> Dict[TypeModelOrEnum, str]: - """ - Process a set of models and generate unique names for them to be used as keys in the JSON Schema - definitions. By default the names are the same as the class name. But if two models in different Python - modules have the same name (e.g. "users.Model" and "items.Model"), the generated names will be - based on the Python module path for those conflicting models to prevent name collisions. - - :param unique_models: a Python set of models - :return: dict mapping models to names - """ - name_model_map = {} - conflicting_names: Set[str] = set() - for model in unique_models: - model_name = normalize_name(model.__name__) - if model_name in conflicting_names: - model_name = get_long_model_name(model) - name_model_map[model_name] = model - elif model_name in name_model_map: - conflicting_names.add(model_name) - conflicting_model = name_model_map.pop(model_name) - name_model_map[get_long_model_name(conflicting_model)] = conflicting_model - name_model_map[get_long_model_name(model)] = model - else: - name_model_map[model_name] = model - return {v: k for k, v in name_model_map.items()} - - -def get_flat_models_from_model(model: Type['BaseModel'], known_models: TypeModelSet = None) -> TypeModelSet: - """ - Take a single ``model`` and generate a set with itself and all the sub-models in the tree. I.e. if you pass - model ``Foo`` (subclass of Pydantic ``BaseModel``) as ``model``, and it has a field of type ``Bar`` (also - subclass of ``BaseModel``) and that model ``Bar`` has a field of type ``Baz`` (also subclass of ``BaseModel``), - the return value will be ``set([Foo, Bar, Baz])``. - - :param model: a Pydantic ``BaseModel`` subclass - :param known_models: used to solve circular references - :return: a set with the initial model and all its sub-models - """ - known_models = known_models or set() - flat_models: TypeModelSet = set() - flat_models.add(model) - known_models |= flat_models - fields = cast(Sequence[ModelField], model.__fields__.values()) - flat_models |= get_flat_models_from_fields(fields, known_models=known_models) - return flat_models - - -def get_flat_models_from_field(field: ModelField, known_models: TypeModelSet) -> TypeModelSet: - """ - Take a single Pydantic ``ModelField`` (from a model) that could have been declared as a sublcass of BaseModel - (so, it could be a submodel), and generate a set with its model and all the sub-models in the tree. - I.e. if you pass a field that was declared to be of type ``Foo`` (subclass of BaseModel) as ``field``, and that - model ``Foo`` has a field of type ``Bar`` (also subclass of ``BaseModel``) and that model ``Bar`` has a field of - type ``Baz`` (also subclass of ``BaseModel``), the return value will be ``set([Foo, Bar, Baz])``. - - :param field: a Pydantic ``ModelField`` - :param known_models: used to solve circular references - :return: a set with the model used in the declaration for this field, if any, and all its sub-models - """ - from .dataclasses import dataclass, is_builtin_dataclass - from .main import BaseModel # noqa: F811 - - flat_models: TypeModelSet = set() - - # Handle dataclass-based models - if is_builtin_dataclass(field.type_): - field.type_ = dataclass(field.type_) - field_type = field.type_ - if lenient_issubclass(getattr(field_type, '__pydantic_model__', None), BaseModel): - field_type = field_type.__pydantic_model__ - if field.sub_fields: - flat_models |= get_flat_models_from_fields(field.sub_fields, known_models=known_models) - elif lenient_issubclass(field_type, BaseModel) and field_type not in known_models: - flat_models |= get_flat_models_from_model(field_type, known_models=known_models) - elif lenient_issubclass(field_type, Enum): - flat_models.add(field_type) - return flat_models - - -def get_flat_models_from_fields(fields: Sequence[ModelField], known_models: TypeModelSet) -> TypeModelSet: - """ - Take a list of Pydantic ``ModelField``s (from a model) that could have been declared as sublcasses of ``BaseModel`` - (so, any of them could be a submodel), and generate a set with their models and all the sub-models in the tree. - I.e. if you pass a the fields of a model ``Foo`` (subclass of ``BaseModel``) as ``fields``, and on of them has a - field of type ``Bar`` (also subclass of ``BaseModel``) and that model ``Bar`` has a field of type ``Baz`` (also - subclass of ``BaseModel``), the return value will be ``set([Foo, Bar, Baz])``. - - :param fields: a list of Pydantic ``ModelField``s - :param known_models: used to solve circular references - :return: a set with any model declared in the fields, and all their sub-models - """ - flat_models: TypeModelSet = set() - for field in fields: - flat_models |= get_flat_models_from_field(field, known_models=known_models) - return flat_models - - -def get_flat_models_from_models(models: Sequence[Type['BaseModel']]) -> TypeModelSet: - """ - Take a list of ``models`` and generate a set with them and all their sub-models in their trees. I.e. if you pass - a list of two models, ``Foo`` and ``Bar``, both subclasses of Pydantic ``BaseModel`` as models, and ``Bar`` has - a field of type ``Baz`` (also subclass of ``BaseModel``), the return value will be ``set([Foo, Bar, Baz])``. - """ - flat_models: TypeModelSet = set() - for model in models: - flat_models |= get_flat_models_from_model(model) - return flat_models - - -def get_long_model_name(model: TypeModelOrEnum) -> str: - return f'{model.__module__}__{model.__name__}'.replace('.', '__') - - -def field_type_schema( - field: ModelField, - *, - by_alias: bool, - model_name_map: Dict[TypeModelOrEnum, str], - ref_template: str, - schema_overrides: bool = False, - ref_prefix: Optional[str] = None, - known_models: TypeModelSet, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - Used by ``field_schema()``, you probably should be using that function. - - Take a single ``field`` and generate the schema for its type only, not including additional - information as title, etc. Also return additional schema definitions, from sub-models. - """ - definitions = {} - nested_models: Set[str] = set() - f_schema: Dict[str, Any] - if field.shape in {SHAPE_LIST, SHAPE_TUPLE_ELLIPSIS, SHAPE_SEQUENCE, SHAPE_SET, SHAPE_FROZENSET, SHAPE_ITERABLE}: - items_schema, f_definitions, f_nested_models = field_singleton_schema( - field, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(f_definitions) - nested_models.update(f_nested_models) - f_schema = {'type': 'array', 'items': items_schema} - if field.shape in {SHAPE_SET, SHAPE_FROZENSET}: - f_schema['uniqueItems'] = True - - elif field.shape == SHAPE_MAPPING: - f_schema = {'type': 'object'} - key_field = cast(ModelField, field.key_field) - regex = getattr(key_field.type_, 'regex', None) - items_schema, f_definitions, f_nested_models = field_singleton_schema( - field, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(f_definitions) - nested_models.update(f_nested_models) - if regex: - # Dict keys have a regex pattern - # items_schema might be a schema or empty dict, add it either way - f_schema['patternProperties'] = {regex.pattern: items_schema} - elif items_schema: - # The dict values are not simply Any, so they need a schema - f_schema['additionalProperties'] = items_schema - elif field.shape == SHAPE_TUPLE: - sub_schema = [] - sub_fields = cast(List[ModelField], field.sub_fields) - for sf in sub_fields: - sf_schema, sf_definitions, sf_nested_models = field_type_schema( - sf, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(sf_definitions) - nested_models.update(sf_nested_models) - sub_schema.append(sf_schema) - if len(sub_schema) == 1: - sub_schema = sub_schema[0] # type: ignore - f_schema = {'type': 'array', 'items': sub_schema} - else: - assert field.shape == SHAPE_SINGLETON, field.shape - f_schema, f_definitions, f_nested_models = field_singleton_schema( - field, - by_alias=by_alias, - model_name_map=model_name_map, - schema_overrides=schema_overrides, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(f_definitions) - nested_models.update(f_nested_models) - - # check field type to avoid repeated calls to the same __modify_schema__ method - if field.type_ != field.outer_type_: - modify_schema = getattr(field.outer_type_, '__modify_schema__', None) - if modify_schema: - modify_schema(f_schema) - return f_schema, definitions, nested_models - - -def model_process_schema( - model: TypeModelOrEnum, - *, - by_alias: bool = True, - model_name_map: Dict[TypeModelOrEnum, str], - ref_prefix: Optional[str] = None, - ref_template: str = default_ref_template, - known_models: TypeModelSet = None, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - Used by ``model_schema()``, you probably should be using that function. - - Take a single ``model`` and generate its schema. Also return additional schema definitions, from sub-models. The - sub-models of the returned schema will be referenced, but their definitions will not be included in the schema. All - the definitions are returned as the second value. - """ - from inspect import getdoc, signature - - known_models = known_models or set() - if lenient_issubclass(model, Enum): - model = cast(Type[Enum], model) - s = enum_process_schema(model) - return s, {}, set() - model = cast(Type['BaseModel'], model) - s = {'title': model.__config__.title or model.__name__} - doc = getdoc(model) - if doc: - s['description'] = doc - known_models.add(model) - m_schema, m_definitions, nested_models = model_type_schema( - model, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - s.update(m_schema) - schema_extra = model.__config__.schema_extra - if callable(schema_extra): - if len(signature(schema_extra).parameters) == 1: - schema_extra(s) - else: - schema_extra(s, model) - else: - s.update(schema_extra) - return s, m_definitions, nested_models - - -def model_type_schema( - model: Type['BaseModel'], - *, - by_alias: bool, - model_name_map: Dict[TypeModelOrEnum, str], - ref_template: str, - ref_prefix: Optional[str] = None, - known_models: TypeModelSet, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - You probably should be using ``model_schema()``, this function is indirectly used by that function. - - Take a single ``model`` and generate the schema for its type only, not including additional - information as title, etc. Also return additional schema definitions, from sub-models. - """ - properties = {} - required = [] - definitions: Dict[str, Any] = {} - nested_models: Set[str] = set() - for k, f in model.__fields__.items(): - try: - f_schema, f_definitions, f_nested_models = field_schema( - f, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - except SkipField as skip: - warnings.warn(skip.message, UserWarning) - continue - definitions.update(f_definitions) - nested_models.update(f_nested_models) - if by_alias: - properties[f.alias] = f_schema - if f.required: - required.append(f.alias) - else: - properties[k] = f_schema - if f.required: - required.append(k) - if ROOT_KEY in properties: - out_schema = properties[ROOT_KEY] - out_schema['title'] = model.__config__.title or model.__name__ - else: - out_schema = {'type': 'object', 'properties': properties} - if required: - out_schema['required'] = required - if model.__config__.extra == 'forbid': - out_schema['additionalProperties'] = False - return out_schema, definitions, nested_models - - -def enum_process_schema(enum: Type[Enum]) -> Dict[str, Any]: - """ - Take a single `enum` and generate its schema. - - This is similar to the `model_process_schema` function, but applies to ``Enum`` objects. - """ - from inspect import getdoc - - schema: Dict[str, Any] = { - 'title': enum.__name__, - # Python assigns all enums a default docstring value of 'An enumeration', so - # all enums will have a description field even if not explicitly provided. - 'description': getdoc(enum), - # Add enum values and the enum field type to the schema. - 'enum': [item.value for item in cast(Iterable[Enum], enum)], - } - - add_field_type_to_schema(enum, schema) - - modify_schema = getattr(enum, '__modify_schema__', None) - if modify_schema: - modify_schema(schema) - - return schema - - -def field_singleton_sub_fields_schema( - sub_fields: Sequence[ModelField], - *, - by_alias: bool, - model_name_map: Dict[TypeModelOrEnum, str], - ref_template: str, - schema_overrides: bool = False, - ref_prefix: Optional[str] = None, - known_models: TypeModelSet, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - This function is indirectly used by ``field_schema()``, you probably should be using that function. - - Take a list of Pydantic ``ModelField`` from the declaration of a type with parameters, and generate their - schema. I.e., fields used as "type parameters", like ``str`` and ``int`` in ``Tuple[str, int]``. - """ - definitions = {} - nested_models: Set[str] = set() - sub_fields = [sf for sf in sub_fields if sf.include_in_schema()] - if len(sub_fields) == 1: - return field_type_schema( - sub_fields[0], - by_alias=by_alias, - model_name_map=model_name_map, - schema_overrides=schema_overrides, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - else: - sub_field_schemas = [] - for sf in sub_fields: - sub_schema, sub_definitions, sub_nested_models = field_type_schema( - sf, - by_alias=by_alias, - model_name_map=model_name_map, - schema_overrides=schema_overrides, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(sub_definitions) - if schema_overrides and 'allOf' in sub_schema: - # if the sub_field is a referenced schema we only need the referenced - # object. Otherwise we will end up with several allOf inside anyOf. - # See https://github.com/samuelcolvin/pydantic/issues/1209 - sub_schema = sub_schema['allOf'][0] - sub_field_schemas.append(sub_schema) - nested_models.update(sub_nested_models) - return {'anyOf': sub_field_schemas}, definitions, nested_models - - -# Order is important, e.g. subclasses of str must go before str -# this is used only for standard library types, custom types should use __modify_schema__ instead -field_class_to_schema: Tuple[Tuple[Any, Dict[str, Any]], ...] = ( - (Path, {'type': 'string', 'format': 'path'}), - (datetime, {'type': 'string', 'format': 'date-time'}), - (date, {'type': 'string', 'format': 'date'}), - (time, {'type': 'string', 'format': 'time'}), - (timedelta, {'type': 'number', 'format': 'time-delta'}), - (IPv4Network, {'type': 'string', 'format': 'ipv4network'}), - (IPv6Network, {'type': 'string', 'format': 'ipv6network'}), - (IPv4Interface, {'type': 'string', 'format': 'ipv4interface'}), - (IPv6Interface, {'type': 'string', 'format': 'ipv6interface'}), - (IPv4Address, {'type': 'string', 'format': 'ipv4'}), - (IPv6Address, {'type': 'string', 'format': 'ipv6'}), - (Pattern, {'type': 'string', 'format': 'regex'}), - (str, {'type': 'string'}), - (bytes, {'type': 'string', 'format': 'binary'}), - (bool, {'type': 'boolean'}), - (int, {'type': 'integer'}), - (float, {'type': 'number'}), - (Decimal, {'type': 'number'}), - (UUID, {'type': 'string', 'format': 'uuid'}), - (dict, {'type': 'object'}), - (list, {'type': 'array', 'items': {}}), - (tuple, {'type': 'array', 'items': {}}), - (set, {'type': 'array', 'items': {}, 'uniqueItems': True}), - (frozenset, {'type': 'array', 'items': {}, 'uniqueItems': True}), -) - -json_scheme = {'type': 'string', 'format': 'json-string'} - - -def add_field_type_to_schema(field_type: Any, schema: Dict[str, Any]) -> None: - """ - Update the given `schema` with the type-specific metadata for the given `field_type`. - - This function looks through `field_class_to_schema` for a class that matches the given `field_type`, - and then modifies the given `schema` with the information from that type. - """ - for type_, t_schema in field_class_to_schema: - # Fallback for `typing.Pattern` as it is not a valid class - if lenient_issubclass(field_type, type_) or field_type is type_ is Pattern: - schema.update(t_schema) - break - - -def get_schema_ref(name: str, ref_prefix: Optional[str], ref_template: str, schema_overrides: bool) -> Dict[str, Any]: - if ref_prefix: - schema_ref = {'$ref': ref_prefix + name} - else: - schema_ref = {'$ref': ref_template.format(model=name)} - return {'allOf': [schema_ref]} if schema_overrides else schema_ref - - -def field_singleton_schema( # noqa: C901 (ignore complexity) - field: ModelField, - *, - by_alias: bool, - model_name_map: Dict[TypeModelOrEnum, str], - ref_template: str, - schema_overrides: bool = False, - ref_prefix: Optional[str] = None, - known_models: TypeModelSet, -) -> Tuple[Dict[str, Any], Dict[str, Any], Set[str]]: - """ - This function is indirectly used by ``field_schema()``, you should probably be using that function. - - Take a single Pydantic ``ModelField``, and return its schema and any additional definitions from sub-models. - """ - from .main import BaseModel # noqa: F811 - - definitions: Dict[str, Any] = {} - nested_models: Set[str] = set() - if field.sub_fields: - return field_singleton_sub_fields_schema( - field.sub_fields, - by_alias=by_alias, - model_name_map=model_name_map, - schema_overrides=schema_overrides, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - if field.type_ is Any or field.type_.__class__ == TypeVar: - return {}, definitions, nested_models # no restrictions - if is_callable_type(field.type_): - raise SkipField(f'Callable {field.name} was excluded from schema since JSON schema has no equivalent type.') - f_schema: Dict[str, Any] = {} - if field.field_info is not None and field.field_info.const: - f_schema['const'] = field.default - field_type = field.type_ - if is_literal_type(field_type): - values = literal_values(field_type) - if len(values) > 1: - return field_schema( - multivalue_literal_field_for_schema(values, field), - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - literal_value = values[0] - field_type = literal_value.__class__ - f_schema['const'] = literal_value - - if lenient_issubclass(field_type, Enum): - enum_name = normalize_name(field_type.__name__) - f_schema, schema_overrides = get_field_info_schema(field) - f_schema.update(get_schema_ref(enum_name, ref_prefix, ref_template, schema_overrides)) - definitions[enum_name] = enum_process_schema(field_type) - else: - add_field_type_to_schema(field_type, f_schema) - - modify_schema = getattr(field_type, '__modify_schema__', None) - if modify_schema: - modify_schema(f_schema) - - if f_schema: - return f_schema, definitions, nested_models - - # Handle dataclass-based models - if lenient_issubclass(getattr(field_type, '__pydantic_model__', None), BaseModel): - field_type = field_type.__pydantic_model__ - - if issubclass(field_type, BaseModel): - model_name = model_name_map[field_type] - if field_type not in known_models: - sub_schema, sub_definitions, sub_nested_models = model_process_schema( - field_type, - by_alias=by_alias, - model_name_map=model_name_map, - ref_prefix=ref_prefix, - ref_template=ref_template, - known_models=known_models, - ) - definitions.update(sub_definitions) - definitions[model_name] = sub_schema - nested_models.update(sub_nested_models) - else: - nested_models.add(model_name) - schema_ref = get_schema_ref(model_name, ref_prefix, ref_template, schema_overrides) - return schema_ref, definitions, nested_models - - raise ValueError(f'Value not declarable with JSON Schema, field: {field}') - - -def multivalue_literal_field_for_schema(values: Tuple[Any, ...], field: ModelField) -> ModelField: - return ModelField( - name=field.name, - type_=Union[tuple(Literal[value] for value in values)], # type: ignore - class_validators=field.class_validators, - model_config=field.model_config, - default=field.default, - required=field.required, - alias=field.alias, - field_info=field.field_info, - ) - - -def encode_default(dft: Any) -> Any: - if isinstance(dft, (int, float, str)): - return dft - elif sequence_like(dft): - t = dft.__class__ - return t(encode_default(v) for v in dft) - elif isinstance(dft, dict): - return {encode_default(k): encode_default(v) for k, v in dft.items()} - elif dft is None: - return None - else: - return pydantic_encoder(dft) - - -_map_types_constraint: Dict[Any, Callable[..., type]] = {int: conint, float: confloat, Decimal: condecimal} -_field_constraints = { - 'min_length', - 'max_length', - 'regex', - 'gt', - 'lt', - 'ge', - 'le', - 'multiple_of', - 'min_items', - 'max_items', -} - - -def get_annotation_from_field_info(annotation: Any, field_info: FieldInfo, field_name: str) -> Type[Any]: # noqa: C901 - """ - Get an annotation with validation implemented for numbers and strings based on the field_info. - - :param annotation: an annotation from a field specification, as ``str``, ``ConstrainedStr`` - :param field_info: an instance of FieldInfo, possibly with declarations for validations and JSON Schema - :param field_name: name of the field for use in error messages - :return: the same ``annotation`` if unmodified or a new annotation with validation in place - """ - constraints = {f for f in _field_constraints if getattr(field_info, f) is not None} - if not constraints: - return annotation - used_constraints: Set[str] = set() - - def go(type_: Any) -> Type[Any]: - if ( - is_literal_type(annotation) - or isinstance(type_, ForwardRef) - or lenient_issubclass(type_, (ConstrainedList, ConstrainedSet)) - ): - return type_ - origin = get_origin(type_) - if origin is not None: - args: Tuple[Any, ...] = get_args(type_) - if any(isinstance(a, ForwardRef) for a in args): - # forward refs cause infinite recursion below - return type_ - - if origin is Union: - return Union[tuple(go(a) for a in args)] # type: ignore - - if issubclass(origin, List) and (field_info.min_items is not None or field_info.max_items is not None): - used_constraints.update({'min_items', 'max_items'}) - return conlist(go(args[0]), min_items=field_info.min_items, max_items=field_info.max_items) - - if issubclass(origin, Set) and (field_info.min_items is not None or field_info.max_items is not None): - used_constraints.update({'min_items', 'max_items'}) - return conset(go(args[0]), min_items=field_info.min_items, max_items=field_info.max_items) - - for t in (Tuple, List, Set, FrozenSet, Sequence): - if issubclass(origin, t): # type: ignore - return t[tuple(go(a) for a in args)] # type: ignore - - if issubclass(origin, Dict): - return Dict[args[0], go(args[1])] # type: ignore - - attrs: Optional[Tuple[str, ...]] = None - constraint_func: Optional[Callable[..., type]] = None - if isinstance(type_, type): - if issubclass(type_, (SecretStr, SecretBytes)): - attrs = ('max_length', 'min_length') - - def constraint_func(**kwargs: Any) -> Type[Any]: - return type(type_.__name__, (type_,), kwargs) - - elif issubclass(type_, str) and not issubclass(type_, (EmailStr, AnyUrl, ConstrainedStr)): - attrs = ('max_length', 'min_length', 'regex') - constraint_func = constr - elif issubclass(type_, bytes): - attrs = ('max_length', 'min_length', 'regex') - constraint_func = conbytes - elif issubclass(type_, numeric_types) and not issubclass( - type_, (ConstrainedInt, ConstrainedFloat, ConstrainedDecimal, ConstrainedList, ConstrainedSet, bool) - ): - # Is numeric type - attrs = ('gt', 'lt', 'ge', 'le', 'multiple_of') - numeric_type = next(t for t in numeric_types if issubclass(type_, t)) # pragma: no branch - constraint_func = _map_types_constraint[numeric_type] - - if attrs: - used_constraints.update(set(attrs)) - kwargs = { - attr_name: attr - for attr_name, attr in ((attr_name, getattr(field_info, attr_name)) for attr_name in attrs) - if attr is not None - } - if kwargs: - constraint_func = cast(Callable[..., type], constraint_func) - return constraint_func(**kwargs) - return type_ - - ans = go(annotation) - - unused_constraints = constraints - used_constraints - if unused_constraints: - raise ValueError( - f'On field "{field_name}" the following field constraints are set but not enforced: ' - f'{", ".join(unused_constraints)}. ' - f'\nFor more details see https://pydantic-docs.helpmanual.io/usage/schema/#unenforced-field-constraints' - ) - - return ans - - -def normalize_name(name: str) -> str: - """ - Normalizes the given name. This can be applied to either a model *or* enum. - """ - return re.sub(r'[^a-zA-Z0-9.\-_]', '_', name) - - -class SkipField(Exception): - """ - Utility exception used to exclude fields from schema. - """ - - def __init__(self, message: str) -> None: - self.message = message diff --git a/env/lib/python3.8/site-packages/pydantic/tools.py b/env/lib/python3.8/site-packages/pydantic/tools.py deleted file mode 100644 index 19d992b4..00000000 --- a/env/lib/python3.8/site-packages/pydantic/tools.py +++ /dev/null @@ -1,79 +0,0 @@ -import json -from functools import lru_cache -from pathlib import Path -from typing import Any, Callable, Optional, Type, TypeVar, Union - -from .parse import Protocol, load_file, load_str_bytes -from .types import StrBytes -from .typing import display_as_type - -__all__ = ('parse_file_as', 'parse_obj_as', 'parse_raw_as') - -NameFactory = Union[str, Callable[[Type[Any]], str]] - - -def _generate_parsing_type_name(type_: Any) -> str: - return f'ParsingModel[{display_as_type(type_)}]' - - -@lru_cache(maxsize=2048) -def _get_parsing_type(type_: Any, *, type_name: Optional[NameFactory] = None) -> Any: - from pydantic.main import create_model - - if type_name is None: - type_name = _generate_parsing_type_name - if not isinstance(type_name, str): - type_name = type_name(type_) - return create_model(type_name, __root__=(type_, ...)) - - -T = TypeVar('T') - - -def parse_obj_as(type_: Type[T], obj: Any, *, type_name: Optional[NameFactory] = None) -> T: - model_type = _get_parsing_type(type_, type_name=type_name) # type: ignore[arg-type] - return model_type(__root__=obj).__root__ - - -def parse_file_as( - type_: Type[T], - path: Union[str, Path], - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - json_loads: Callable[[str], Any] = json.loads, - type_name: Optional[NameFactory] = None, -) -> T: - obj = load_file( - path, - proto=proto, - content_type=content_type, - encoding=encoding, - allow_pickle=allow_pickle, - json_loads=json_loads, - ) - return parse_obj_as(type_, obj, type_name=type_name) - - -def parse_raw_as( - type_: Type[T], - b: StrBytes, - *, - content_type: str = None, - encoding: str = 'utf8', - proto: Protocol = None, - allow_pickle: bool = False, - json_loads: Callable[[str], Any] = json.loads, - type_name: Optional[NameFactory] = None, -) -> T: - obj = load_str_bytes( - b, - proto=proto, - content_type=content_type, - encoding=encoding, - allow_pickle=allow_pickle, - json_loads=json_loads, - ) - return parse_obj_as(type_, obj, type_name=type_name) diff --git a/env/lib/python3.8/site-packages/pydantic/types.py b/env/lib/python3.8/site-packages/pydantic/types.py deleted file mode 100644 index 9c462e12..00000000 --- a/env/lib/python3.8/site-packages/pydantic/types.py +++ /dev/null @@ -1,874 +0,0 @@ -import math -import re -import warnings -from decimal import Decimal -from enum import Enum -from pathlib import Path -from types import new_class -from typing import ( - TYPE_CHECKING, - Any, - Callable, - ClassVar, - Dict, - List, - Optional, - Pattern, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) -from uuid import UUID - -from . import errors -from .utils import import_string, update_not_none -from .validators import ( - bytes_validator, - constr_length_validator, - constr_strip_whitespace, - decimal_validator, - float_validator, - int_validator, - list_validator, - number_multiple_validator, - number_size_validator, - path_exists_validator, - path_validator, - set_validator, - str_validator, - strict_float_validator, - strict_int_validator, - strict_str_validator, -) - -__all__ = [ - 'NoneStr', - 'NoneBytes', - 'StrBytes', - 'NoneStrBytes', - 'StrictStr', - 'ConstrainedBytes', - 'conbytes', - 'ConstrainedList', - 'conlist', - 'ConstrainedSet', - 'conset', - 'ConstrainedStr', - 'constr', - 'PyObject', - 'ConstrainedInt', - 'conint', - 'PositiveInt', - 'NegativeInt', - 'ConstrainedFloat', - 'confloat', - 'PositiveFloat', - 'NegativeFloat', - 'ConstrainedDecimal', - 'condecimal', - 'UUID1', - 'UUID3', - 'UUID4', - 'UUID5', - 'FilePath', - 'DirectoryPath', - 'Json', - 'JsonWrapper', - 'SecretStr', - 'SecretBytes', - 'StrictBool', - 'StrictInt', - 'StrictFloat', - 'PaymentCardNumber', - 'ByteSize', -] - -NoneStr = Optional[str] -NoneBytes = Optional[bytes] -StrBytes = Union[str, bytes] -NoneStrBytes = Optional[StrBytes] -OptionalInt = Optional[int] -OptionalIntFloat = Union[OptionalInt, float] -OptionalIntFloatDecimal = Union[OptionalIntFloat, Decimal] -StrIntFloat = Union[str, int, float] - -if TYPE_CHECKING: - from .dataclasses import Dataclass # noqa: F401 - from .fields import ModelField - from .main import BaseConfig, BaseModel # noqa: F401 - from .typing import CallableGenerator - - ModelOrDc = Type[Union['BaseModel', 'Dataclass']] - - -class ConstrainedBytes(bytes): - strip_whitespace = False - min_length: OptionalInt = None - max_length: OptionalInt = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none(field_schema, minLength=cls.min_length, maxLength=cls.max_length) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield bytes_validator - yield constr_strip_whitespace - yield constr_length_validator - - -def conbytes(*, strip_whitespace: bool = False, min_length: int = None, max_length: int = None) -> Type[bytes]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict(strip_whitespace=strip_whitespace, min_length=min_length, max_length=max_length) - return type('ConstrainedBytesValue', (ConstrainedBytes,), namespace) - - -T = TypeVar('T') - - -# This types superclass should be List[T], but cython chokes on that... -class ConstrainedList(list): # type: ignore - # Needed for pydantic to detect that this is a list - __origin__ = list - __args__: Tuple[Type[T], ...] # type: ignore - - min_items: Optional[int] = None - max_items: Optional[int] = None - item_type: Type[T] # type: ignore - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.list_length_validator - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none(field_schema, minItems=cls.min_items, maxItems=cls.max_items) - - @classmethod - def list_length_validator(cls, v: 'Optional[List[T]]', field: 'ModelField') -> 'Optional[List[T]]': - if v is None and not field.required: - return None - - v = list_validator(v) - v_len = len(v) - - if cls.min_items is not None and v_len < cls.min_items: - raise errors.ListMinLengthError(limit_value=cls.min_items) - - if cls.max_items is not None and v_len > cls.max_items: - raise errors.ListMaxLengthError(limit_value=cls.max_items) - - return v - - -def conlist(item_type: Type[T], *, min_items: int = None, max_items: int = None) -> Type[List[T]]: - # __args__ is needed to conform to typing generics api - namespace = {'min_items': min_items, 'max_items': max_items, 'item_type': item_type, '__args__': (item_type,)} - # We use new_class to be able to deal with Generic types - return new_class('ConstrainedListValue', (ConstrainedList,), {}, lambda ns: ns.update(namespace)) - - -# This types superclass should be Set[T], but cython chokes on that... -class ConstrainedSet(set): # type: ignore - # Needed for pydantic to detect that this is a set - __origin__ = set - __args__: Set[Type[T]] # type: ignore - - min_items: Optional[int] = None - max_items: Optional[int] = None - item_type: Type[T] # type: ignore - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.set_length_validator - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none(field_schema, minItems=cls.min_items, maxItems=cls.max_items) - - @classmethod - def set_length_validator(cls, v: 'Optional[Set[T]]', field: 'ModelField') -> 'Optional[Set[T]]': - v = set_validator(v) - v_len = len(v) - - if cls.min_items is not None and v_len < cls.min_items: - raise errors.SetMinLengthError(limit_value=cls.min_items) - - if cls.max_items is not None and v_len > cls.max_items: - raise errors.SetMaxLengthError(limit_value=cls.max_items) - - return v - - -def conset(item_type: Type[T], *, min_items: int = None, max_items: int = None) -> Type[Set[T]]: - # __args__ is needed to conform to typing generics api - namespace = {'min_items': min_items, 'max_items': max_items, 'item_type': item_type, '__args__': [item_type]} - # We use new_class to be able to deal with Generic types - return new_class('ConstrainedSetValue', (ConstrainedSet,), {}, lambda ns: ns.update(namespace)) - - -class ConstrainedStr(str): - strip_whitespace = False - min_length: OptionalInt = None - max_length: OptionalInt = None - curtail_length: OptionalInt = None - regex: Optional[Pattern[str]] = None - strict = False - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, minLength=cls.min_length, maxLength=cls.max_length, pattern=cls.regex and cls.regex.pattern - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield strict_str_validator if cls.strict else str_validator - yield constr_strip_whitespace - yield constr_length_validator - yield cls.validate - - @classmethod - def validate(cls, value: Union[str]) -> Union[str]: - if cls.curtail_length and len(value) > cls.curtail_length: - value = value[: cls.curtail_length] - - if cls.regex: - if not cls.regex.match(value): - raise errors.StrRegexError(pattern=cls.regex.pattern) - - return value - - -def constr( - *, - strip_whitespace: bool = False, - strict: bool = False, - min_length: int = None, - max_length: int = None, - curtail_length: int = None, - regex: str = None, -) -> Type[str]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict( - strip_whitespace=strip_whitespace, - strict=strict, - min_length=min_length, - max_length=max_length, - curtail_length=curtail_length, - regex=regex and re.compile(regex), - ) - return type('ConstrainedStrValue', (ConstrainedStr,), namespace) - - -class StrictStr(ConstrainedStr): - strict = True - - -if TYPE_CHECKING: - StrictBool = bool -else: - - class StrictBool(int): - """ - StrictBool to allow for bools which are not type-coerced. - """ - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='boolean') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: Any) -> bool: - """ - Ensure that we only allow bools. - """ - if isinstance(value, bool): - return value - - raise errors.StrictBoolError() - - -class PyObject: - validate_always = True - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, value: Any) -> Any: - if isinstance(value, Callable): # type: ignore - return value - - try: - value = str_validator(value) - except errors.StrError: - raise errors.PyObjectError(error_message='value is neither a valid import path not a valid callable') - - try: - return import_string(value) - except ImportError as e: - raise errors.PyObjectError(error_message=str(e)) - - if TYPE_CHECKING: - - def __call__(self, *args: Any, **kwargs: Any) -> Any: - ... - - -class ConstrainedNumberMeta(type): - def __new__(cls, name: str, bases: Any, dct: Dict[str, Any]) -> 'ConstrainedInt': # type: ignore - new_cls = cast('ConstrainedInt', type.__new__(cls, name, bases, dct)) - - if new_cls.gt is not None and new_cls.ge is not None: - raise errors.ConfigError('bounds gt and ge cannot be specified at the same time') - if new_cls.lt is not None and new_cls.le is not None: - raise errors.ConfigError('bounds lt and le cannot be specified at the same time') - - return new_cls - - -class ConstrainedInt(int, metaclass=ConstrainedNumberMeta): - strict: bool = False - gt: OptionalInt = None - ge: OptionalInt = None - lt: OptionalInt = None - le: OptionalInt = None - multiple_of: OptionalInt = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, - exclusiveMinimum=cls.gt, - exclusiveMaximum=cls.lt, - minimum=cls.ge, - maximum=cls.le, - multipleOf=cls.multiple_of, - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - - yield strict_int_validator if cls.strict else int_validator - yield number_size_validator - yield number_multiple_validator - - -def conint( - *, strict: bool = False, gt: int = None, ge: int = None, lt: int = None, le: int = None, multiple_of: int = None -) -> Type[int]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict(strict=strict, gt=gt, ge=ge, lt=lt, le=le, multiple_of=multiple_of) - return type('ConstrainedIntValue', (ConstrainedInt,), namespace) - - -class PositiveInt(ConstrainedInt): - gt = 0 - - -class NegativeInt(ConstrainedInt): - lt = 0 - - -class StrictInt(ConstrainedInt): - strict = True - - -class ConstrainedFloat(float, metaclass=ConstrainedNumberMeta): - strict: bool = False - gt: OptionalIntFloat = None - ge: OptionalIntFloat = None - lt: OptionalIntFloat = None - le: OptionalIntFloat = None - multiple_of: OptionalIntFloat = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, - exclusiveMinimum=cls.gt, - exclusiveMaximum=cls.lt, - minimum=cls.ge, - maximum=cls.le, - multipleOf=cls.multiple_of, - ) - # Modify constraints to account for differences between IEEE floats and JSON - if field_schema.get('exclusiveMinimum') == -math.inf: - del field_schema['exclusiveMinimum'] - if field_schema.get('minimum') == -math.inf: - del field_schema['minimum'] - if field_schema.get('exclusiveMaximum') == math.inf: - del field_schema['exclusiveMaximum'] - if field_schema.get('maximum') == math.inf: - del field_schema['maximum'] - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield strict_float_validator if cls.strict else float_validator - yield number_size_validator - yield number_multiple_validator - - -def confloat( - *, - strict: bool = False, - gt: float = None, - ge: float = None, - lt: float = None, - le: float = None, - multiple_of: float = None, -) -> Type[float]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict(strict=strict, gt=gt, ge=ge, lt=lt, le=le, multiple_of=multiple_of) - return type('ConstrainedFloatValue', (ConstrainedFloat,), namespace) - - -class PositiveFloat(ConstrainedFloat): - gt = 0 - - -class NegativeFloat(ConstrainedFloat): - lt = 0 - - -class StrictFloat(ConstrainedFloat): - strict = True - - -class ConstrainedDecimal(Decimal, metaclass=ConstrainedNumberMeta): - gt: OptionalIntFloatDecimal = None - ge: OptionalIntFloatDecimal = None - lt: OptionalIntFloatDecimal = None - le: OptionalIntFloatDecimal = None - max_digits: OptionalInt = None - decimal_places: OptionalInt = None - multiple_of: OptionalIntFloatDecimal = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, - exclusiveMinimum=cls.gt, - exclusiveMaximum=cls.lt, - minimum=cls.ge, - maximum=cls.le, - multipleOf=cls.multiple_of, - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield decimal_validator - yield number_size_validator - yield number_multiple_validator - yield cls.validate - - @classmethod - def validate(cls, value: Decimal) -> Decimal: - digit_tuple, exponent = value.as_tuple()[1:] - if exponent in {'F', 'n', 'N'}: - raise errors.DecimalIsNotFiniteError() - - if exponent >= 0: - # A positive exponent adds that many trailing zeros. - digits = len(digit_tuple) + exponent - decimals = 0 - else: - # If the absolute value of the negative exponent is larger than the - # number of digits, then it's the same as the number of digits, - # because it'll consume all of the digits in digit_tuple and then - # add abs(exponent) - len(digit_tuple) leading zeros after the - # decimal point. - if abs(exponent) > len(digit_tuple): - digits = decimals = abs(exponent) - else: - digits = len(digit_tuple) - decimals = abs(exponent) - whole_digits = digits - decimals - - if cls.max_digits is not None and digits > cls.max_digits: - raise errors.DecimalMaxDigitsError(max_digits=cls.max_digits) - - if cls.decimal_places is not None and decimals > cls.decimal_places: - raise errors.DecimalMaxPlacesError(decimal_places=cls.decimal_places) - - if cls.max_digits is not None and cls.decimal_places is not None: - expected = cls.max_digits - cls.decimal_places - if whole_digits > expected: - raise errors.DecimalWholeDigitsError(whole_digits=expected) - - return value - - -def condecimal( - *, - gt: Decimal = None, - ge: Decimal = None, - lt: Decimal = None, - le: Decimal = None, - max_digits: int = None, - decimal_places: int = None, - multiple_of: Decimal = None, -) -> Type[Decimal]: - # use kwargs then define conf in a dict to aid with IDE type hinting - namespace = dict( - gt=gt, ge=ge, lt=lt, le=le, max_digits=max_digits, decimal_places=decimal_places, multiple_of=multiple_of - ) - return type('ConstrainedDecimalValue', (ConstrainedDecimal,), namespace) - - -class UUID1(UUID): - _required_version = 1 - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format=f'uuid{cls._required_version}') - - -class UUID3(UUID1): - _required_version = 3 - - -class UUID4(UUID1): - _required_version = 4 - - -class UUID5(UUID1): - _required_version = 5 - - -class FilePath(Path): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(format='file-path') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield path_validator - yield path_exists_validator - yield cls.validate - - @classmethod - def validate(cls, value: Path) -> Path: - if not value.is_file(): - raise errors.PathNotAFileError(path=value) - - return value - - -class DirectoryPath(Path): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(format='directory-path') - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield path_validator - yield path_exists_validator - yield cls.validate - - @classmethod - def validate(cls, value: Path) -> Path: - if not value.is_dir(): - raise errors.PathNotADirectoryError(path=value) - - return value - - -class JsonWrapper: - pass - - -class JsonMeta(type): - def __getitem__(self, t: Type[Any]) -> Type[JsonWrapper]: - return type('JsonWrapperValue', (JsonWrapper,), {'inner_type': t}) - - -class Json(metaclass=JsonMeta): - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - field_schema.update(type='string', format='json-string') - - -class SecretStr: - min_length: OptionalInt = None - max_length: OptionalInt = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, - type='string', - writeOnly=True, - format='password', - minLength=cls.min_length, - maxLength=cls.max_length, - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - yield constr_length_validator - - @classmethod - def validate(cls, value: Any) -> 'SecretStr': - if isinstance(value, cls): - return value - value = str_validator(value) - return cls(value) - - def __init__(self, value: str): - self._secret_value = value - - def __repr__(self) -> str: - return f"SecretStr('{self}')" - - def __str__(self) -> str: - return '**********' if self._secret_value else '' - - def __eq__(self, other: Any) -> bool: - return isinstance(other, SecretStr) and self.get_secret_value() == other.get_secret_value() - - def __len__(self) -> int: - return len(self._secret_value) - - def display(self) -> str: - warnings.warn('`secret_str.display()` is deprecated, use `str(secret_str)` instead', DeprecationWarning) - return str(self) - - def get_secret_value(self) -> str: - return self._secret_value - - -class SecretBytes: - min_length: OptionalInt = None - max_length: OptionalInt = None - - @classmethod - def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: - update_not_none( - field_schema, - type='string', - writeOnly=True, - format='password', - minLength=cls.min_length, - maxLength=cls.max_length, - ) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - yield constr_length_validator - - @classmethod - def validate(cls, value: Any) -> 'SecretBytes': - if isinstance(value, cls): - return value - value = bytes_validator(value) - return cls(value) - - def __init__(self, value: bytes): - self._secret_value = value - - def __repr__(self) -> str: - return f"SecretBytes(b'{self}')" - - def __str__(self) -> str: - return '**********' if self._secret_value else '' - - def __eq__(self, other: Any) -> bool: - return isinstance(other, SecretBytes) and self.get_secret_value() == other.get_secret_value() - - def __len__(self) -> int: - return len(self._secret_value) - - def display(self) -> str: - warnings.warn('`secret_bytes.display()` is deprecated, use `str(secret_bytes)` instead', DeprecationWarning) - return str(self) - - def get_secret_value(self) -> bytes: - return self._secret_value - - -class PaymentCardBrand(str, Enum): - amex = 'American Express' - mastercard = 'Mastercard' - visa = 'Visa' - other = 'other' - - def __str__(self) -> str: - return self.value - - -class PaymentCardNumber(str): - """ - Based on: https://en.wikipedia.org/wiki/Payment_card_number - """ - - strip_whitespace: ClassVar[bool] = True - min_length: ClassVar[int] = 12 - max_length: ClassVar[int] = 19 - bin: str - last4: str - brand: PaymentCardBrand - - def __init__(self, card_number: str): - self.bin = card_number[:6] - self.last4 = card_number[-4:] - self.brand = self._get_brand(card_number) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield str_validator - yield constr_strip_whitespace - yield constr_length_validator - yield cls.validate_digits - yield cls.validate_luhn_check_digit - yield cls - yield cls.validate_length_for_brand - - @property - def masked(self) -> str: - num_masked = len(self) - 10 # len(bin) + len(last4) == 10 - return f'{self.bin}{"*" * num_masked}{self.last4}' - - @classmethod - def validate_digits(cls, card_number: str) -> str: - if not card_number.isdigit(): - raise errors.NotDigitError - return card_number - - @classmethod - def validate_luhn_check_digit(cls, card_number: str) -> str: - """ - Based on: https://en.wikipedia.org/wiki/Luhn_algorithm - """ - sum_ = int(card_number[-1]) - length = len(card_number) - parity = length % 2 - for i in range(length - 1): - digit = int(card_number[i]) - if i % 2 == parity: - digit *= 2 - if digit > 9: - digit -= 9 - sum_ += digit - valid = sum_ % 10 == 0 - if not valid: - raise errors.LuhnValidationError - return card_number - - @classmethod - def validate_length_for_brand(cls, card_number: 'PaymentCardNumber') -> 'PaymentCardNumber': - """ - Validate length based on BIN for major brands: - https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN) - """ - required_length: Optional[int] = None - if card_number.brand in {PaymentCardBrand.visa, PaymentCardBrand.mastercard}: - required_length = 16 - valid = len(card_number) == required_length - elif card_number.brand == PaymentCardBrand.amex: - required_length = 15 - valid = len(card_number) == required_length - else: - valid = True - if not valid: - raise errors.InvalidLengthForBrand(brand=card_number.brand, required_length=required_length) - return card_number - - @staticmethod - def _get_brand(card_number: str) -> PaymentCardBrand: - if card_number[0] == '4': - brand = PaymentCardBrand.visa - elif 51 <= int(card_number[:2]) <= 55: - brand = PaymentCardBrand.mastercard - elif card_number[:2] in {'34', '37'}: - brand = PaymentCardBrand.amex - else: - brand = PaymentCardBrand.other - return brand - - -BYTE_SIZES = { - 'b': 1, - 'kb': 10 ** 3, - 'mb': 10 ** 6, - 'gb': 10 ** 9, - 'tb': 10 ** 12, - 'pb': 10 ** 15, - 'eb': 10 ** 18, - 'kib': 2 ** 10, - 'mib': 2 ** 20, - 'gib': 2 ** 30, - 'tib': 2 ** 40, - 'pib': 2 ** 50, - 'eib': 2 ** 60, -} -BYTE_SIZES.update({k.lower()[0]: v for k, v in BYTE_SIZES.items() if 'i' not in k}) -byte_string_re = re.compile(r'^\s*(\d*\.?\d+)\s*(\w+)?', re.IGNORECASE) - - -class ByteSize(int): - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield cls.validate - - @classmethod - def validate(cls, v: StrIntFloat) -> 'ByteSize': - - try: - return cls(int(v)) - except ValueError: - pass - - str_match = byte_string_re.match(str(v)) - if str_match is None: - raise errors.InvalidByteSize() - - scalar, unit = str_match.groups() - if unit is None: - unit = 'b' - - try: - unit_mult = BYTE_SIZES[unit.lower()] - except KeyError: - raise errors.InvalidByteSizeUnit(unit=unit) - - return cls(int(float(scalar) * unit_mult)) - - def human_readable(self, decimal: bool = False) -> str: - - if decimal: - divisor = 1000 - units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] - final_unit = 'EB' - else: - divisor = 1024 - units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'] - final_unit = 'EiB' - - num = float(self) - for unit in units: - if abs(num) < divisor: - return f'{num:0.1f}{unit}' - num /= divisor - - return f'{num:0.1f}{final_unit}' - - def to(self, unit: str) -> float: - - try: - unit_div = BYTE_SIZES[unit.lower()] - except KeyError: - raise errors.InvalidByteSizeUnit(unit=unit) - - return self / unit_div diff --git a/env/lib/python3.8/site-packages/pydantic/typing.py b/env/lib/python3.8/site-packages/pydantic/typing.py deleted file mode 100644 index e71228f6..00000000 --- a/env/lib/python3.8/site-packages/pydantic/typing.py +++ /dev/null @@ -1,315 +0,0 @@ -import sys -from enum import Enum -from typing import ( # type: ignore - TYPE_CHECKING, - AbstractSet, - Any, - ClassVar, - Dict, - Generator, - List, - Mapping, - NewType, - Optional, - Sequence, - Set, - Tuple, - Type, - Union, - _eval_type, - cast, -) - -try: - from typing import _TypingBase as typing_base # type: ignore -except ImportError: - from typing import _Final as typing_base # type: ignore - - -if sys.version_info < (3, 7): - if TYPE_CHECKING: - - class ForwardRef: - def __init__(self, arg: Any): - pass - - def _eval_type(self, globalns: Any, localns: Any) -> Any: - pass - - else: - from typing import _ForwardRef as ForwardRef -else: - from typing import ForwardRef - - -if sys.version_info < (3, 7): - - def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any: - return type_._eval_type(globalns, localns) - - -elif sys.version_info < (3, 9): - - def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any: - return type_._evaluate(globalns, localns) - - -else: - - def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any: - # Even though it is the right signature for python 3.9, mypy complains with - # `error: Too many arguments for "_evaluate" of "ForwardRef"` hence the cast... - return cast(Any, type_)._evaluate(globalns, localns, set()) - - -if sys.version_info < (3, 7): - from typing import Callable as Callable - - AnyCallable = Callable[..., Any] - NoArgAnyCallable = Callable[[], Any] -else: - from collections.abc import Callable as Callable - from typing import Callable as TypingCallable - - AnyCallable = TypingCallable[..., Any] - NoArgAnyCallable = TypingCallable[[], Any] - -if sys.version_info < (3, 8): - if TYPE_CHECKING: - from typing_extensions import Literal - else: # due to different mypy warnings raised during CI for python 3.7 and 3.8 - try: - from typing_extensions import Literal - except ImportError: - Literal = None - - def get_args(t: Type[Any]) -> Tuple[Any, ...]: - return getattr(t, '__args__', ()) - - def get_origin(t: Type[Any]) -> Optional[Type[Any]]: - return getattr(t, '__origin__', None) - - -else: - from typing import Literal, get_args as typing_get_args, get_origin as typing_get_origin - - def get_origin(tp: Type[Any]) -> Type[Any]: - """ - We can't directly use `typing.get_origin` since we need a fallback to support - custom generic classes like `ConstrainedList` - It should be useless once https://github.com/cython/cython/issues/3537 is - solved and https://github.com/samuelcolvin/pydantic/pull/1753 is merged. - """ - return typing_get_origin(tp) or getattr(tp, '__origin__', None) - - def generic_get_args(tp: Type[Any]) -> Tuple[Any, ...]: - """ - In python 3.9, `typing.Dict`, `typing.List`, ... - do have an empty `__args__` by default (instead of the generic ~T for example). - In order to still support `Dict` for example and consider it as `Dict[Any, Any]`, - we retrieve the `_nparams` value that tells us how many parameters it needs. - """ - if hasattr(tp, '_nparams'): - return (Any,) * tp._nparams - return () - - def get_args(tp: Type[Any]) -> Tuple[Any, ...]: - """Get type arguments with all substitutions performed. - - For unions, basic simplifications used by Union constructor are performed. - Examples:: - get_args(Dict[str, int]) == (str, int) - get_args(int) == () - get_args(Union[int, Union[T, int], str][int]) == (int, str) - get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - get_args(Callable[[], T][int]) == ([], int) - """ - # the fallback is needed for the same reasons as `get_origin` (see above) - return typing_get_args(tp) or getattr(tp, '__args__', ()) or generic_get_args(tp) - - -if TYPE_CHECKING: - from .fields import ModelField - - TupleGenerator = Generator[Tuple[str, Any], None, None] - DictStrAny = Dict[str, Any] - DictAny = Dict[Any, Any] - SetStr = Set[str] - ListStr = List[str] - IntStr = Union[int, str] - AbstractSetIntStr = AbstractSet[IntStr] - DictIntStrAny = Dict[IntStr, Any] - MappingIntStrAny = Mapping[IntStr, Any] - CallableGenerator = Generator[AnyCallable, None, None] - ReprArgs = Sequence[Tuple[Optional[str], Any]] - -__all__ = ( - 'ForwardRef', - 'Callable', - 'AnyCallable', - 'NoArgAnyCallable', - 'NoneType', - 'display_as_type', - 'resolve_annotations', - 'is_callable_type', - 'is_literal_type', - 'literal_values', - 'Literal', - 'is_new_type', - 'new_type_supertype', - 'is_classvar', - 'update_field_forward_refs', - 'TupleGenerator', - 'DictStrAny', - 'DictAny', - 'SetStr', - 'ListStr', - 'IntStr', - 'AbstractSetIntStr', - 'DictIntStrAny', - 'CallableGenerator', - 'ReprArgs', - 'CallableGenerator', - 'get_args', - 'get_origin', -) - - -NoneType = None.__class__ - - -def display_as_type(v: Type[Any]) -> str: - if not isinstance(v, typing_base) and not isinstance(v, type): - v = v.__class__ - - if isinstance(v, type) and issubclass(v, Enum): - if issubclass(v, int): - return 'int' - elif issubclass(v, str): - return 'str' - else: - return 'enum' - - try: - return v.__name__ - except AttributeError: - # happens with typing objects - return str(v).replace('typing.', '') - - -def resolve_annotations(raw_annotations: Dict[str, Type[Any]], module_name: Optional[str]) -> Dict[str, Type[Any]]: - """ - Partially taken from typing.get_type_hints. - - Resolve string or ForwardRef annotations into type objects if possible. - """ - if module_name: - base_globals: Optional[Dict[str, Any]] = sys.modules[module_name].__dict__ - else: - base_globals = None - annotations = {} - for name, value in raw_annotations.items(): - if isinstance(value, str): - if sys.version_info >= (3, 7): - value = ForwardRef(value, is_argument=False) - else: - value = ForwardRef(value) - try: - value = _eval_type(value, base_globals, None) - except NameError: - # this is ok, it can be fixed with update_forward_refs - pass - annotations[name] = value - return annotations - - -def is_callable_type(type_: Type[Any]) -> bool: - return type_ is Callable or get_origin(type_) is Callable - - -if sys.version_info >= (3, 7): - - def is_literal_type(type_: Type[Any]) -> bool: - return Literal is not None and get_origin(type_) is Literal - - def literal_values(type_: Type[Any]) -> Tuple[Any, ...]: - return get_args(type_) - - -else: - - def is_literal_type(type_: Type[Any]) -> bool: - return Literal is not None and hasattr(type_, '__values__') and type_ == Literal[type_.__values__] - - def literal_values(type_: Type[Any]) -> Tuple[Any, ...]: - return type_.__values__ - - -def all_literal_values(type_: Type[Any]) -> Tuple[Any, ...]: - """ - This method is used to retrieve all Literal values as - Literal can be used recursively (see https://www.python.org/dev/peps/pep-0586) - e.g. `Literal[Literal[Literal[1, 2, 3], "foo"], 5, None]` - """ - if not is_literal_type(type_): - return (type_,) - - values = literal_values(type_) - return tuple(x for value in values for x in all_literal_values(value)) - - -test_type = NewType('test_type', str) - - -def is_new_type(type_: Type[Any]) -> bool: - """ - Check whether type_ was created using typing.NewType - """ - return isinstance(type_, test_type.__class__) and hasattr(type_, '__supertype__') # type: ignore - - -def new_type_supertype(type_: Type[Any]) -> Type[Any]: - while hasattr(type_, '__supertype__'): - type_ = type_.__supertype__ - return type_ - - -def _check_classvar(v: Optional[Type[Any]]) -> bool: - if v is None: - return False - - return v.__class__ == ClassVar.__class__ and (sys.version_info < (3, 7) or getattr(v, '_name', None) == 'ClassVar') - - -def is_classvar(ann_type: Type[Any]) -> bool: - return _check_classvar(ann_type) or _check_classvar(get_origin(ann_type)) - - -def update_field_forward_refs(field: 'ModelField', globalns: Any, localns: Any) -> None: - """ - Try to update ForwardRefs on fields based on this ModelField, globalns and localns. - """ - if field.type_.__class__ == ForwardRef: - field.type_ = evaluate_forwardref(field.type_, globalns, localns or None) - field.prepare() - if field.sub_fields: - for sub_f in field.sub_fields: - update_field_forward_refs(sub_f, globalns=globalns, localns=localns) - - -def get_class(type_: Type[Any]) -> Union[None, bool, Type[Any]]: - """ - Tries to get the class of a Type[T] annotation. Returns True if Type is used - without brackets. Otherwise returns None. - """ - try: - origin = get_origin(type_) - if origin is None: # Python 3.6 - origin = type_ - if issubclass(origin, Type): # type: ignore - if not get_args(type_) or not isinstance(get_args(type_)[0], type): - return True - return get_args(type_)[0] - except (AttributeError, TypeError): - pass - return None diff --git a/env/lib/python3.8/site-packages/pydantic/utils.py b/env/lib/python3.8/site-packages/pydantic/utils.py deleted file mode 100644 index 4592223d..00000000 --- a/env/lib/python3.8/site-packages/pydantic/utils.py +++ /dev/null @@ -1,634 +0,0 @@ -import warnings -import weakref -from collections import OrderedDict, defaultdict, deque -from copy import deepcopy -from itertools import islice -from types import BuiltinFunctionType, CodeType, FunctionType, GeneratorType, LambdaType, ModuleType -from typing import ( - TYPE_CHECKING, - AbstractSet, - Any, - Callable, - Dict, - Generator, - Iterator, - List, - Mapping, - Optional, - Set, - Tuple, - Type, - TypeVar, - Union, - no_type_check, -) - -from .typing import NoneType, display_as_type -from .version import version_info - -if TYPE_CHECKING: - from inspect import Signature - from pathlib import Path - - from .dataclasses import Dataclass # noqa: F401 - from .fields import ModelField # noqa: F401 - from .main import BaseConfig, BaseModel # noqa: F401 - from .typing import AbstractSetIntStr, DictIntStrAny, IntStr, MappingIntStrAny, ReprArgs # noqa: F401 - -__all__ = ( - 'import_string', - 'sequence_like', - 'validate_field_name', - 'lenient_issubclass', - 'in_ipython', - 'deep_update', - 'update_not_none', - 'almost_equal_floats', - 'get_model', - 'to_camel', - 'is_valid_field', - 'smart_deepcopy', - 'PyObjectStr', - 'Representation', - 'GetterDict', - 'ValueItems', - 'version_info', # required here to match behaviour in v1.3 - 'ClassAttribute', - 'path_type', - 'ROOT_KEY', -) - -ROOT_KEY = '__root__' -# these are types that are returned unchanged by deepcopy -IMMUTABLE_NON_COLLECTIONS_TYPES: Set[Type[Any]] = { - int, - float, - complex, - str, - bool, - bytes, - type, - NoneType, - FunctionType, - BuiltinFunctionType, - LambdaType, - weakref.ref, - CodeType, - # note: including ModuleType will differ from behaviour of deepcopy by not producing error. - # It might be not a good idea in general, but considering that this function used only internally - # against default values of fields, this will allow to actually have a field with module as default value - ModuleType, - NotImplemented.__class__, - Ellipsis.__class__, -} - -# these are types that if empty, might be copied with simple copy() instead of deepcopy() -BUILTIN_COLLECTIONS: Set[Type[Any]] = { - list, - set, - tuple, - frozenset, - dict, - OrderedDict, - defaultdict, - deque, -} - - -def import_string(dotted_path: str) -> Any: - """ - Stolen approximately from django. Import a dotted module path and return the attribute/class designated by the - last name in the path. Raise ImportError if the import fails. - """ - from importlib import import_module - - try: - module_path, class_name = dotted_path.strip(' ').rsplit('.', 1) - except ValueError as e: - raise ImportError(f'"{dotted_path}" doesn\'t look like a module path') from e - - module = import_module(module_path) - try: - return getattr(module, class_name) - except AttributeError as e: - raise ImportError(f'Module "{module_path}" does not define a "{class_name}" attribute') from e - - -def truncate(v: Union[str], *, max_len: int = 80) -> str: - """ - Truncate a value and add a unicode ellipsis (three dots) to the end if it was too long - """ - warnings.warn('`truncate` is no-longer used by pydantic and is deprecated', DeprecationWarning) - if isinstance(v, str) and len(v) > (max_len - 2): - # -3 so quote + string + … + quote has correct length - return (v[: (max_len - 3)] + '…').__repr__() - try: - v = v.__repr__() - except TypeError: - v = v.__class__.__repr__(v) # in case v is a type - if len(v) > max_len: - v = v[: max_len - 1] + '…' - return v - - -def sequence_like(v: Type[Any]) -> bool: - return isinstance(v, (list, tuple, set, frozenset, GeneratorType, deque)) - - -def validate_field_name(bases: List[Type['BaseModel']], field_name: str) -> None: - """ - Ensure that the field's name does not shadow an existing attribute of the model. - """ - for base in bases: - if getattr(base, field_name, None): - raise NameError( - f'Field name "{field_name}" shadows a BaseModel attribute; ' - f'use a different field name with "alias=\'{field_name}\'".' - ) - - -def lenient_issubclass(cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool: - return isinstance(cls, type) and issubclass(cls, class_or_tuple) - - -def in_ipython() -> bool: - """ - Check whether we're in an ipython environment, including jupyter notebooks. - """ - try: - eval('__IPYTHON__') - except NameError: - return False - else: # pragma: no cover - return True - - -KeyType = TypeVar('KeyType') - - -def deep_update(mapping: Dict[KeyType, Any], *updating_mappings: Dict[KeyType, Any]) -> Dict[KeyType, Any]: - updated_mapping = mapping.copy() - for updating_mapping in updating_mappings: - for k, v in updating_mapping.items(): - if k in updated_mapping and isinstance(updated_mapping[k], dict) and isinstance(v, dict): - updated_mapping[k] = deep_update(updated_mapping[k], v) - else: - updated_mapping[k] = v - return updated_mapping - - -def update_not_none(mapping: Dict[Any, Any], **update: Any) -> None: - mapping.update({k: v for k, v in update.items() if v is not None}) - - -def almost_equal_floats(value_1: float, value_2: float, *, delta: float = 1e-8) -> bool: - """ - Return True if two floats are almost equal - """ - return abs(value_1 - value_2) <= delta - - -def generate_model_signature( - init: Callable[..., None], fields: Dict[str, 'ModelField'], config: Type['BaseConfig'] -) -> 'Signature': - """ - Generate signature for model based on its fields - """ - from inspect import Parameter, Signature, signature - - present_params = signature(init).parameters.values() - merged_params: Dict[str, Parameter] = {} - var_kw = None - use_var_kw = False - - for param in islice(present_params, 1, None): # skip self arg - if param.kind is param.VAR_KEYWORD: - var_kw = param - continue - merged_params[param.name] = param - - if var_kw: # if custom init has no var_kw, fields which are not declared in it cannot be passed through - allow_names = config.allow_population_by_field_name - for field_name, field in fields.items(): - param_name = field.alias - if field_name in merged_params or param_name in merged_params: - continue - elif not param_name.isidentifier(): - if allow_names and field_name.isidentifier(): - param_name = field_name - else: - use_var_kw = True - continue - - # TODO: replace annotation with actual expected types once #1055 solved - kwargs = {'default': field.default} if not field.required else {} - merged_params[param_name] = Parameter( - param_name, Parameter.KEYWORD_ONLY, annotation=field.outer_type_, **kwargs - ) - - if config.extra is config.extra.allow: - use_var_kw = True - - if var_kw and use_var_kw: - # Make sure the parameter for extra kwargs - # does not have the same name as a field - default_model_signature = [ - ('__pydantic_self__', Parameter.POSITIONAL_OR_KEYWORD), - ('data', Parameter.VAR_KEYWORD), - ] - if [(p.name, p.kind) for p in present_params] == default_model_signature: - # if this is the standard model signature, use extra_data as the extra args name - var_kw_name = 'extra_data' - else: - # else start from var_kw - var_kw_name = var_kw.name - - # generate a name that's definitely unique - while var_kw_name in fields: - var_kw_name += '_' - merged_params[var_kw_name] = var_kw.replace(name=var_kw_name) - - return Signature(parameters=list(merged_params.values()), return_annotation=None) - - -def get_model(obj: Union[Type['BaseModel'], Type['Dataclass']]) -> Type['BaseModel']: - from .main import BaseModel # noqa: F811 - - try: - model_cls = obj.__pydantic_model__ # type: ignore - except AttributeError: - model_cls = obj - - if not issubclass(model_cls, BaseModel): - raise TypeError('Unsupported type, must be either BaseModel or dataclass') - return model_cls - - -def to_camel(string: str) -> str: - return ''.join(word.capitalize() for word in string.split('_')) - - -T = TypeVar('T') - - -def unique_list(input_list: Union[List[T], Tuple[T, ...]]) -> List[T]: - """ - Make a list unique while maintaining order. - """ - result = [] - unique_set = set() - for v in input_list: - if v not in unique_set: - unique_set.add(v) - result.append(v) - - return result - - -def update_normalized_all( - item: Union['AbstractSetIntStr', 'MappingIntStrAny'], - all_items: Union['AbstractSetIntStr', 'MappingIntStrAny'], -) -> Union['AbstractSetIntStr', 'MappingIntStrAny']: - """ - Update item based on what all items contains. - - The update is done based on these cases: - - - if both arguments are dicts then each key-value pair existing in ``all_items`` is merged into ``item``, - while the rest of the key-value pairs are updated recursively with this function. - - if both arguments are sets then they are just merged. - - if ``item`` is a dictionary and ``all_items`` is a set then all values of it are added to ``item`` as - ``key: ...``. - - if ``item`` is set and ``all_items`` is a dictionary, then ``item`` is converted to a dictionary and then the - key-value pairs of ``all_items`` are merged in it. - - During recursive calls, there is a case where ``all_items`` can be an Ellipsis, in which case the ``item`` is - returned as is. - """ - if not item: - return all_items - if isinstance(item, dict) and isinstance(all_items, dict): - item = dict(item) - item.update({k: update_normalized_all(item[k], v) for k, v in all_items.items() if k in item}) - item.update({k: v for k, v in all_items.items() if k not in item}) - return item - if isinstance(item, set) and isinstance(all_items, set): - item = set(item) - item.update(all_items) - return item - if isinstance(item, dict) and isinstance(all_items, set): - item = dict(item) - item.update({k: ... for k in all_items if k not in item}) - return item - if isinstance(item, set) and isinstance(all_items, dict): - item = {k: ... for k in item} - item.update({k: v for k, v in all_items.items() if k not in item}) - return item - # Case when item or all_items is ... (in recursive calls). - return item - - -class PyObjectStr(str): - """ - String class where repr doesn't include quotes. Useful with Representation when you want to return a string - representation of something that valid (or pseudo-valid) python. - """ - - def __repr__(self) -> str: - return str(self) - - -class Representation: - """ - Mixin to provide __str__, __repr__, and __pretty__ methods. See #884 for more details. - - __pretty__ is used by [devtools](https://python-devtools.helpmanual.io/) to provide human readable representations - of objects. - """ - - __slots__: Tuple[str, ...] = tuple() - - def __repr_args__(self) -> 'ReprArgs': - """ - Returns the attributes to show in __str__, __repr__, and __pretty__ this is generally overridden. - - Can either return: - * name - value pairs, e.g.: `[('foo_name', 'foo'), ('bar_name', ['b', 'a', 'r'])]` - * or, just values, e.g.: `[(None, 'foo'), (None, ['b', 'a', 'r'])]` - """ - attrs = ((s, getattr(self, s)) for s in self.__slots__) - return [(a, v) for a, v in attrs if v is not None] - - def __repr_name__(self) -> str: - """ - Name of the instance's class, used in __repr__. - """ - return self.__class__.__name__ - - def __repr_str__(self, join_str: str) -> str: - return join_str.join(repr(v) if a is None else f'{a}={v!r}' for a, v in self.__repr_args__()) - - def __pretty__(self, fmt: Callable[[Any], Any], **kwargs: Any) -> Generator[Any, None, None]: - """ - Used by devtools (https://python-devtools.helpmanual.io/) to provide a human readable representations of objects - """ - yield self.__repr_name__() + '(' - yield 1 - for name, value in self.__repr_args__(): - if name is not None: - yield name + '=' - yield fmt(value) - yield ',' - yield 0 - yield -1 - yield ')' - - def __str__(self) -> str: - return self.__repr_str__(' ') - - def __repr__(self) -> str: - return f'{self.__repr_name__()}({self.__repr_str__(", ")})' - - -class GetterDict(Representation): - """ - Hack to make object's smell just enough like dicts for validate_model. - - We can't inherit from Mapping[str, Any] because it upsets cython so we have to implement all methods ourselves. - """ - - __slots__ = ('_obj',) - - def __init__(self, obj: Any): - self._obj = obj - - def __getitem__(self, key: str) -> Any: - try: - return getattr(self._obj, key) - except AttributeError as e: - raise KeyError(key) from e - - def get(self, key: Any, default: Any = None) -> Any: - return getattr(self._obj, key, default) - - def extra_keys(self) -> Set[Any]: - """ - We don't want to get any other attributes of obj if the model didn't explicitly ask for them - """ - return set() - - def keys(self) -> List[Any]: - """ - Keys of the pseudo dictionary, uses a list not set so order information can be maintained like python - dictionaries. - """ - return list(self) - - def values(self) -> List[Any]: - return [self[k] for k in self] - - def items(self) -> Iterator[Tuple[str, Any]]: - for k in self: - yield k, self.get(k) - - def __iter__(self) -> Iterator[str]: - for name in dir(self._obj): - if not name.startswith('_'): - yield name - - def __len__(self) -> int: - return sum(1 for _ in self) - - def __contains__(self, item: Any) -> bool: - return item in self.keys() - - def __eq__(self, other: Any) -> bool: - return dict(self) == dict(other.items()) - - def __repr_args__(self) -> 'ReprArgs': - return [(None, dict(self))] - - def __repr_name__(self) -> str: - return f'GetterDict[{display_as_type(self._obj)}]' - - -class ValueItems(Representation): - """ - Class for more convenient calculation of excluded or included fields on values. - """ - - __slots__ = ('_items', '_type') - - def __init__(self, value: Any, items: Union['AbstractSetIntStr', 'MappingIntStrAny']) -> None: - if TYPE_CHECKING: - self._items: Union['AbstractSetIntStr', 'MappingIntStrAny'] - self._type: Type[Union[set, dict]] # type: ignore - - # For further type checks speed-up - if isinstance(items, Mapping): - self._type = dict - elif isinstance(items, AbstractSet): - self._type = set - else: - raise TypeError(f'Unexpected type of exclude value {items.__class__}') - - if isinstance(value, (list, tuple)): - items = self._normalize_indexes(items, len(value)) - - self._items = items - - @no_type_check - def is_excluded(self, item: Any) -> bool: - """ - Check if item is fully excluded - (value considered excluded if self._type is set and item contained in self._items - or self._type is dict and self._items.get(item) is ... - - :param item: key or index of a value - """ - if self._type is set: - return item in self._items - return self._items.get(item) is ... - - @no_type_check - def is_included(self, item: Any) -> bool: - """ - Check if value is contained in self._items - - :param item: key or index of value - """ - return item in self._items - - @no_type_check - def for_element(self, e: 'IntStr') -> Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']]: - """ - :param e: key or index of element on value - :return: raw values for elemet if self._items is dict and contain needed element - """ - - if self._type is dict: - item = self._items.get(e) - return item if item is not ... else None - return None - - @no_type_check - def _normalize_indexes( - self, items: Union['AbstractSetIntStr', 'MappingIntStrAny'], v_length: int - ) -> Union['AbstractSetIntStr', 'DictIntStrAny']: - """ - :param items: dict or set of indexes which will be normalized - :param v_length: length of sequence indexes of which will be - - >>> self._normalize_indexes({0, -2, -1}, 4) - {0, 2, 3} - >>> self._normalize_indexes({'__all__'}, 4) - {0, 1, 2, 3} - """ - if any(not isinstance(i, int) and i != '__all__' for i in items): - raise TypeError( - 'Excluding fields from a sequence of sub-models or dicts must be performed index-wise: ' - 'expected integer keys or keyword "__all__"' - ) - if self._type is set: - if '__all__' in items: - if items != {'__all__'}: - raise ValueError('set with keyword "__all__" must not contain other elements') - return {i for i in range(v_length)} - return {v_length + i if i < 0 else i for i in items} - else: - all_items = items.get('__all__') - for i, v in items.items(): - if not (isinstance(v, Mapping) or isinstance(v, AbstractSet) or v is ...): - raise TypeError(f'Unexpected type of exclude value for index "{i}" {v.__class__}') - normalized_items = {v_length + i if i < 0 else i: v for i, v in items.items() if i != '__all__'} - if all_items: - default: Type[Union[Set[Any], Dict[Any, Any]]] - if isinstance(all_items, Mapping): - default = dict - elif isinstance(all_items, AbstractSet): - default = set - else: - for i in range(v_length): - normalized_items.setdefault(i, ...) - return normalized_items - for i in range(v_length): - normalized_item = normalized_items.setdefault(i, default()) - if normalized_item is not ...: - normalized_items[i] = update_normalized_all(normalized_item, all_items) - return normalized_items - - def __repr_args__(self) -> 'ReprArgs': - return [(None, self._items)] - - -class ClassAttribute: - """ - Hide class attribute from its instances - """ - - __slots__ = ( - 'name', - 'value', - ) - - def __init__(self, name: str, value: Any) -> None: - self.name = name - self.value = value - - def __get__(self, instance: Any, owner: Type[Any]) -> None: - if instance is None: - return self.value - raise AttributeError(f'{self.name!r} attribute of {owner.__name__!r} is class-only') - - -path_types = { - 'is_dir': 'directory', - 'is_file': 'file', - 'is_mount': 'mount point', - 'is_symlink': 'symlink', - 'is_block_device': 'block device', - 'is_char_device': 'char device', - 'is_fifo': 'FIFO', - 'is_socket': 'socket', -} - - -def path_type(p: 'Path') -> str: - """ - Find out what sort of thing a path is. - """ - assert p.exists(), 'path does not exist' - for method, name in path_types.items(): - if getattr(p, method)(): - return name - - return 'unknown' - - -Obj = TypeVar('Obj') - - -def smart_deepcopy(obj: Obj) -> Obj: - """ - Return type as is for immutable built-in types - Use obj.copy() for built-in empty collections - Use copy.deepcopy() for non-empty collections and unknown objects - """ - - obj_type = obj.__class__ - if obj_type in IMMUTABLE_NON_COLLECTIONS_TYPES: - return obj # fastest case: obj is immutable and not collection therefore will not be copied anyway - elif not obj and obj_type in BUILTIN_COLLECTIONS: - # faster way for empty collections, no need to copy its members - return obj if obj_type is tuple else obj.copy() # type: ignore # tuple doesn't have copy method - return deepcopy(obj) # slowest way when we actually might need a deepcopy - - -def is_valid_field(name: str) -> bool: - if not name.startswith('_'): - return True - return ROOT_KEY == name - - -def is_valid_private_name(name: str) -> bool: - return not is_valid_field(name) and name not in {'__annotations__', '__classcell__', '__module__', '__qualname__'} diff --git a/env/lib/python3.8/site-packages/pydantic/validators.py b/env/lib/python3.8/site-packages/pydantic/validators.py deleted file mode 100644 index 5beb4ea7..00000000 --- a/env/lib/python3.8/site-packages/pydantic/validators.py +++ /dev/null @@ -1,629 +0,0 @@ -import re -from collections import OrderedDict, deque -from collections.abc import Hashable -from datetime import date, datetime, time, timedelta -from decimal import Decimal, DecimalException -from enum import Enum, IntEnum -from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network -from pathlib import Path -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Deque, - Dict, - FrozenSet, - Generator, - List, - Pattern, - Set, - Tuple, - Type, - TypeVar, - Union, -) -from uuid import UUID - -from . import errors -from .datetime_parse import parse_date, parse_datetime, parse_duration, parse_time -from .typing import ( - AnyCallable, - ForwardRef, - all_literal_values, - display_as_type, - get_class, - is_callable_type, - is_literal_type, -) -from .utils import almost_equal_floats, lenient_issubclass, sequence_like - -if TYPE_CHECKING: - from .fields import ModelField - from .main import BaseConfig - from .types import ConstrainedDecimal, ConstrainedFloat, ConstrainedInt - - ConstrainedNumber = Union[ConstrainedDecimal, ConstrainedFloat, ConstrainedInt] - AnyOrderedDict = OrderedDict[Any, Any] - Number = Union[int, float, Decimal] - StrBytes = Union[str, bytes] - - -def str_validator(v: Any) -> Union[str]: - if isinstance(v, str): - if isinstance(v, Enum): - return v.value - else: - return v - elif isinstance(v, (float, int, Decimal)): - # is there anything else we want to add here? If you think so, create an issue. - return str(v) - elif isinstance(v, (bytes, bytearray)): - return v.decode() - else: - raise errors.StrError() - - -def strict_str_validator(v: Any) -> Union[str]: - if isinstance(v, str): - return v - raise errors.StrError() - - -def bytes_validator(v: Any) -> bytes: - if isinstance(v, bytes): - return v - elif isinstance(v, bytearray): - return bytes(v) - elif isinstance(v, str): - return v.encode() - elif isinstance(v, (float, int, Decimal)): - return str(v).encode() - else: - raise errors.BytesError() - - -BOOL_FALSE = {0, '0', 'off', 'f', 'false', 'n', 'no'} -BOOL_TRUE = {1, '1', 'on', 't', 'true', 'y', 'yes'} - - -def bool_validator(v: Any) -> bool: - if v is True or v is False: - return v - if isinstance(v, bytes): - v = v.decode() - if isinstance(v, str): - v = v.lower() - try: - if v in BOOL_TRUE: - return True - if v in BOOL_FALSE: - return False - except TypeError: - raise errors.BoolError() - raise errors.BoolError() - - -def int_validator(v: Any) -> int: - if isinstance(v, int) and not (v is True or v is False): - return v - - try: - return int(v) - except (TypeError, ValueError): - raise errors.IntegerError() - - -def strict_int_validator(v: Any) -> int: - if isinstance(v, int) and not (v is True or v is False): - return v - raise errors.IntegerError() - - -def float_validator(v: Any) -> float: - if isinstance(v, float): - return v - - try: - return float(v) - except (TypeError, ValueError): - raise errors.FloatError() - - -def strict_float_validator(v: Any) -> float: - if isinstance(v, float): - return v - raise errors.FloatError() - - -def number_multiple_validator(v: 'Number', field: 'ModelField') -> 'Number': - field_type: ConstrainedNumber = field.type_ - if field_type.multiple_of is not None: - mod = float(v) / float(field_type.multiple_of) % 1 - if not almost_equal_floats(mod, 0.0) and not almost_equal_floats(mod, 1.0): - raise errors.NumberNotMultipleError(multiple_of=field_type.multiple_of) - return v - - -def number_size_validator(v: 'Number', field: 'ModelField') -> 'Number': - field_type: ConstrainedNumber = field.type_ - if field_type.gt is not None and not v > field_type.gt: - raise errors.NumberNotGtError(limit_value=field_type.gt) - elif field_type.ge is not None and not v >= field_type.ge: - raise errors.NumberNotGeError(limit_value=field_type.ge) - - if field_type.lt is not None and not v < field_type.lt: - raise errors.NumberNotLtError(limit_value=field_type.lt) - if field_type.le is not None and not v <= field_type.le: - raise errors.NumberNotLeError(limit_value=field_type.le) - - return v - - -def constant_validator(v: 'Any', field: 'ModelField') -> 'Any': - """Validate ``const`` fields. - - The value provided for a ``const`` field must be equal to the default value - of the field. This is to support the keyword of the same name in JSON - Schema. - """ - if v != field.default: - raise errors.WrongConstantError(given=v, permitted=[field.default]) - - return v - - -def anystr_length_validator(v: 'StrBytes', config: 'BaseConfig') -> 'StrBytes': - v_len = len(v) - - min_length = config.min_anystr_length - if min_length is not None and v_len < min_length: - raise errors.AnyStrMinLengthError(limit_value=min_length) - - max_length = config.max_anystr_length - if max_length is not None and v_len > max_length: - raise errors.AnyStrMaxLengthError(limit_value=max_length) - - return v - - -def anystr_strip_whitespace(v: 'StrBytes') -> 'StrBytes': - return v.strip() - - -def ordered_dict_validator(v: Any) -> 'AnyOrderedDict': - if isinstance(v, OrderedDict): - return v - - try: - return OrderedDict(v) - except (TypeError, ValueError): - raise errors.DictError() - - -def dict_validator(v: Any) -> Dict[Any, Any]: - if isinstance(v, dict): - return v - - try: - return dict(v) - except (TypeError, ValueError): - raise errors.DictError() - - -def list_validator(v: Any) -> List[Any]: - if isinstance(v, list): - return v - elif sequence_like(v): - return list(v) - else: - raise errors.ListError() - - -def tuple_validator(v: Any) -> Tuple[Any, ...]: - if isinstance(v, tuple): - return v - elif sequence_like(v): - return tuple(v) - else: - raise errors.TupleError() - - -def set_validator(v: Any) -> Set[Any]: - if isinstance(v, set): - return v - elif sequence_like(v): - return set(v) - else: - raise errors.SetError() - - -def frozenset_validator(v: Any) -> FrozenSet[Any]: - if isinstance(v, frozenset): - return v - elif sequence_like(v): - return frozenset(v) - else: - raise errors.FrozenSetError() - - -def deque_validator(v: Any) -> Deque[Any]: - if isinstance(v, deque): - return v - elif sequence_like(v): - return deque(v) - else: - raise errors.DequeError() - - -def enum_member_validator(v: Any, field: 'ModelField', config: 'BaseConfig') -> Enum: - try: - enum_v = field.type_(v) - except ValueError: - # field.type_ should be an enum, so will be iterable - raise errors.EnumMemberError(enum_values=list(field.type_)) - return enum_v.value if config.use_enum_values else enum_v - - -def uuid_validator(v: Any, field: 'ModelField') -> UUID: - try: - if isinstance(v, str): - v = UUID(v) - elif isinstance(v, (bytes, bytearray)): - try: - v = UUID(v.decode()) - except ValueError: - # 16 bytes in big-endian order as the bytes argument fail - # the above check - v = UUID(bytes=v) - except ValueError: - raise errors.UUIDError() - - if not isinstance(v, UUID): - raise errors.UUIDError() - - required_version = getattr(field.type_, '_required_version', None) - if required_version and v.version != required_version: - raise errors.UUIDVersionError(required_version=required_version) - - return v - - -def decimal_validator(v: Any) -> Decimal: - if isinstance(v, Decimal): - return v - elif isinstance(v, (bytes, bytearray)): - v = v.decode() - - v = str(v).strip() - - try: - v = Decimal(v) - except DecimalException: - raise errors.DecimalError() - - if not v.is_finite(): - raise errors.DecimalIsNotFiniteError() - - return v - - -def hashable_validator(v: Any) -> Hashable: - if isinstance(v, Hashable): - return v - - raise errors.HashableError() - - -def ip_v4_address_validator(v: Any) -> IPv4Address: - if isinstance(v, IPv4Address): - return v - - try: - return IPv4Address(v) - except ValueError: - raise errors.IPv4AddressError() - - -def ip_v6_address_validator(v: Any) -> IPv6Address: - if isinstance(v, IPv6Address): - return v - - try: - return IPv6Address(v) - except ValueError: - raise errors.IPv6AddressError() - - -def ip_v4_network_validator(v: Any) -> IPv4Network: - """ - Assume IPv4Network initialised with a default ``strict`` argument - - See more: - https://docs.python.org/library/ipaddress.html#ipaddress.IPv4Network - """ - if isinstance(v, IPv4Network): - return v - - try: - return IPv4Network(v) - except ValueError: - raise errors.IPv4NetworkError() - - -def ip_v6_network_validator(v: Any) -> IPv6Network: - """ - Assume IPv6Network initialised with a default ``strict`` argument - - See more: - https://docs.python.org/library/ipaddress.html#ipaddress.IPv6Network - """ - if isinstance(v, IPv6Network): - return v - - try: - return IPv6Network(v) - except ValueError: - raise errors.IPv6NetworkError() - - -def ip_v4_interface_validator(v: Any) -> IPv4Interface: - if isinstance(v, IPv4Interface): - return v - - try: - return IPv4Interface(v) - except ValueError: - raise errors.IPv4InterfaceError() - - -def ip_v6_interface_validator(v: Any) -> IPv6Interface: - if isinstance(v, IPv6Interface): - return v - - try: - return IPv6Interface(v) - except ValueError: - raise errors.IPv6InterfaceError() - - -def path_validator(v: Any) -> Path: - if isinstance(v, Path): - return v - - try: - return Path(v) - except TypeError: - raise errors.PathError() - - -def path_exists_validator(v: Any) -> Path: - if not v.exists(): - raise errors.PathNotExistsError(path=v) - - return v - - -def callable_validator(v: Any) -> AnyCallable: - """ - Perform a simple check if the value is callable. - - Note: complete matching of argument type hints and return types is not performed - """ - if callable(v): - return v - - raise errors.CallableError(value=v) - - -def enum_validator(v: Any) -> Enum: - if isinstance(v, Enum): - return v - - raise errors.EnumError(value=v) - - -def int_enum_validator(v: Any) -> IntEnum: - if isinstance(v, IntEnum): - return v - - raise errors.IntEnumError(value=v) - - -def make_literal_validator(type_: Any) -> Callable[[Any], Any]: - permitted_choices = all_literal_values(type_) - allowed_choices_set = set(permitted_choices) - - def literal_validator(v: Any) -> Any: - if v not in allowed_choices_set: - raise errors.WrongConstantError(given=v, permitted=permitted_choices) - return v - - return literal_validator - - -def constr_length_validator(v: 'StrBytes', field: 'ModelField', config: 'BaseConfig') -> 'StrBytes': - v_len = len(v) - - min_length = field.type_.min_length or config.min_anystr_length - if min_length is not None and v_len < min_length: - raise errors.AnyStrMinLengthError(limit_value=min_length) - - max_length = field.type_.max_length or config.max_anystr_length - if max_length is not None and v_len > max_length: - raise errors.AnyStrMaxLengthError(limit_value=max_length) - - return v - - -def constr_strip_whitespace(v: 'StrBytes', field: 'ModelField', config: 'BaseConfig') -> 'StrBytes': - strip_whitespace = field.type_.strip_whitespace or config.anystr_strip_whitespace - if strip_whitespace: - v = v.strip() - - return v - - -def validate_json(v: Any, config: 'BaseConfig') -> Any: - if v is None: - # pass None through to other validators - return v - try: - return config.json_loads(v) # type: ignore - except ValueError: - raise errors.JsonError() - except TypeError: - raise errors.JsonTypeError() - - -T = TypeVar('T') - - -def make_arbitrary_type_validator(type_: Type[T]) -> Callable[[T], T]: - def arbitrary_type_validator(v: Any) -> T: - if isinstance(v, type_): - return v - raise errors.ArbitraryTypeError(expected_arbitrary_type=type_) - - return arbitrary_type_validator - - -def make_class_validator(type_: Type[T]) -> Callable[[Any], Type[T]]: - def class_validator(v: Any) -> Type[T]: - if lenient_issubclass(v, type_): - return v - raise errors.SubclassError(expected_class=type_) - - return class_validator - - -def any_class_validator(v: Any) -> Type[T]: - if isinstance(v, type): - return v - raise errors.ClassError() - - -def pattern_validator(v: Any) -> Pattern[str]: - if isinstance(v, Pattern): - return v - - str_value = str_validator(v) - - try: - return re.compile(str_value) - except re.error: - raise errors.PatternError() - - -class IfConfig: - def __init__(self, validator: AnyCallable, *config_attr_names: str) -> None: - self.validator = validator - self.config_attr_names = config_attr_names - - def check(self, config: Type['BaseConfig']) -> bool: - return any(getattr(config, name) not in {None, False} for name in self.config_attr_names) - - -# order is important here, for example: bool is a subclass of int so has to come first, datetime before date same, -# IPv4Interface before IPv4Address, etc -_VALIDATORS: List[Tuple[Type[Any], List[Any]]] = [ - (IntEnum, [int_validator, enum_member_validator]), - (Enum, [enum_member_validator]), - ( - str, - [ - str_validator, - IfConfig(anystr_strip_whitespace, 'anystr_strip_whitespace'), - IfConfig(anystr_length_validator, 'min_anystr_length', 'max_anystr_length'), - ], - ), - ( - bytes, - [ - bytes_validator, - IfConfig(anystr_strip_whitespace, 'anystr_strip_whitespace'), - IfConfig(anystr_length_validator, 'min_anystr_length', 'max_anystr_length'), - ], - ), - (bool, [bool_validator]), - (int, [int_validator]), - (float, [float_validator]), - (Path, [path_validator]), - (datetime, [parse_datetime]), - (date, [parse_date]), - (time, [parse_time]), - (timedelta, [parse_duration]), - (OrderedDict, [ordered_dict_validator]), - (dict, [dict_validator]), - (list, [list_validator]), - (tuple, [tuple_validator]), - (set, [set_validator]), - (frozenset, [frozenset_validator]), - (deque, [deque_validator]), - (UUID, [uuid_validator]), - (Decimal, [decimal_validator]), - (IPv4Interface, [ip_v4_interface_validator]), - (IPv6Interface, [ip_v6_interface_validator]), - (IPv4Address, [ip_v4_address_validator]), - (IPv6Address, [ip_v6_address_validator]), - (IPv4Network, [ip_v4_network_validator]), - (IPv6Network, [ip_v6_network_validator]), -] - - -def find_validators( # noqa: C901 (ignore complexity) - type_: Type[Any], config: Type['BaseConfig'] -) -> Generator[AnyCallable, None, None]: - from .dataclasses import is_builtin_dataclass, make_dataclass_validator - - if type_ is Any: - return - type_type = type_.__class__ - if type_type == ForwardRef or type_type == TypeVar: - return - if type_ is Pattern: - yield pattern_validator - return - if type_ is Hashable: - yield hashable_validator - return - if is_callable_type(type_): - yield callable_validator - return - if is_literal_type(type_): - yield make_literal_validator(type_) - return - if is_builtin_dataclass(type_): - yield from make_dataclass_validator(type_, config) - return - if type_ is Enum: - yield enum_validator - return - if type_ is IntEnum: - yield int_enum_validator - return - - class_ = get_class(type_) - if class_ is not None: - if isinstance(class_, type): - yield make_class_validator(class_) - else: - yield any_class_validator - return - - for val_type, validators in _VALIDATORS: - try: - if issubclass(type_, val_type): - for v in validators: - if isinstance(v, IfConfig): - if v.check(config): - yield v.validator - else: - yield v - return - except TypeError: - raise RuntimeError(f'error checking inheritance of {type_!r} (type: {display_as_type(type_)})') - - if config.arbitrary_types_allowed: - yield make_arbitrary_type_validator(type_) - else: - raise RuntimeError(f'no validator found for {type_}, see `arbitrary_types_allowed` in Config') diff --git a/env/lib/python3.8/site-packages/pydantic/version.py b/env/lib/python3.8/site-packages/pydantic/version.py deleted file mode 100644 index cd81ee5f..00000000 --- a/env/lib/python3.8/site-packages/pydantic/version.py +++ /dev/null @@ -1,30 +0,0 @@ -__all__ = 'VERSION', 'version_info' - -VERSION = '1.7.2' - - -def version_info() -> str: - import platform - import sys - from importlib import import_module - from pathlib import Path - - from .main import compiled - - optional_deps = [] - for p in ('typing-extensions', 'email-validator', 'devtools'): - try: - import_module(p.replace('-', '_')) - except ImportError: - continue - optional_deps.append(p) - - info = { - 'pydantic version': VERSION, - 'pydantic compiled': compiled, - 'install path': Path(__file__).resolve().parent, - 'python version': sys.version, - 'platform': platform.platform(), - 'optional deps. installed': optional_deps, - } - return '\n'.join('{:>30} {}'.format(k + ':', str(v).replace('\n', ' ')) for k, v in info.items()) diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/COPYING b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/COPYING deleted file mode 100644 index 8c4c849e..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -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 give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 Program -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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), 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 Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. 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 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 St, 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 Library General -Public License instead of this License. diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/INSTALLER b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/METADATA b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/METADATA deleted file mode 100644 index f2a37851..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/METADATA +++ /dev/null @@ -1,205 +0,0 @@ -Metadata-Version: 2.1 -Name: pylint -Version: 2.6.0 -Summary: python code static checker -Home-page: https://github.com/PyCQA/pylint -Author: Python Code Quality Authority -Author-email: code-quality@python.org -License: GPL -Project-URL: What's New, https://pylint.pycqa.org/en/latest/whatsnew/ -Platform: UNKNOWN -Classifier: Development Status :: 6 - Mature -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: GNU General Public License (GPL) -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Software Development :: Debuggers -Classifier: Topic :: Software Development :: Quality Assurance -Classifier: Topic :: Software Development :: Testing -Requires-Python: >=3.5.* -Requires-Dist: astroid (<=2.5,>=2.4.0) -Requires-Dist: isort (<6,>=4.2.5) -Requires-Dist: mccabe (<0.7,>=0.6) -Requires-Dist: toml (>=0.7.1) -Requires-Dist: colorama ; sys_platform=="win32" - - -README for Pylint - https://pylint.pycqa.org/ -============================================= - -.. image:: https://travis-ci.org/PyCQA/pylint.svg?branch=master - :target: https://travis-ci.org/PyCQA/pylint - -.. image:: https://ci.appveyor.com/api/projects/status/rbvwhakyj1y09atb/branch/master?svg=true - :alt: AppVeyor Build Status - :target: https://ci.appveyor.com/project/PCManticore/pylint - -.. image:: https://coveralls.io/repos/github/PyCQA/pylint/badge.svg?branch=master - :target: https://coveralls.io/github/PyCQA/pylint?branch=master - - -.. image:: https://img.shields.io/pypi/v/pylint.svg - :alt: Pypi Package version - :target: https://pypi.python.org/pypi/pylint - -.. image:: https://readthedocs.org/projects/pylint/badge/?version=latest - :target: https://pylint.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 - -.. |tideliftlogo| image:: doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png - :width: 75 - :height: 60 - :alt: Tidelift - -.. list-table:: - :widths: 10 100 - - * - |tideliftlogo| - - Professional support for pylint is available as part of the `Tidelift - Subscription`_. Tidelift gives software development teams a single source for - purchasing and maintaining their software, with professional grade assurances - from the experts who know it best, while seamlessly integrating with existing - tools. - -.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme - - -====== -Pylint -====== - -**It's not just a linter that annoys you!** - -Pylint is a Python static code analysis tool which looks for programming errors, -helps enforcing a coding standard, sniffs for code smells and offers simple refactoring -suggestions. - -It's highly configurable, having special pragmas to control its errors and warnings -from within your code, as well as from an extensive configuration file. -It is also possible to write your own plugins for adding your own checks or for -extending pylint in one way or another. - -It's a free software distributed under the GNU General Public Licence unless -otherwise specified. - -Development is hosted on GitHub: https://github.com/PyCQA/pylint/ - -You can use the code-quality@python.org mailing list to discuss about -Pylint. Subscribe at https://mail.python.org/mailman/listinfo/code-quality/ -or read the archives at https://mail.python.org/pipermail/code-quality/ - -Pull requests are amazing and most welcome. - -Install -------- - -Pylint can be simply installed by running:: - - pip install pylint - -If you are using Python 3.6+, upgrade to get full support for your version:: - - pip install pylint --upgrade - -If you want to install from a source distribution, extract the tarball and run -the following command :: - - python setup.py install - - -Do make sure to do the same for astroid, which is used internally by pylint. - -For debian and rpm packages, use your usual tools according to your Linux distribution. - -More information about installation and available distribution format -can be found here_. - -Documentation -------------- - -The documentation lives at https://pylint.pycqa.org/. - -Pylint is shipped with following additional commands: - -* pyreverse: an UML diagram generator -* symilar: an independent similarities checker -* epylint: Emacs and Flymake compatible Pylint - - -Testing -------- - -We use tox_ for running the test suite. You should be able to install it with:: - - pip install tox pytest - - -To run the test suite for a particular Python version, you can do:: - - tox -e py37 - - -To run individual tests with ``tox``, you can do:: - - tox -e py37 -- -k name_of_the_test - - -We use pytest_ for testing ``pylint``, which you can use without using ``tox`` for a faster development cycle. - -If you want to run tests on a specific portion of the code with pytest_, (pytest-cov_) and your local python version:: - - # ( pip install pytest-cov ) - # Everything: - python3 -m pytest tests/ - # Everything in tests/message with coverage for the relevant code: - python3 -m pytest tests/message/ --cov=pylint.message - coverage html - # Only the functional test "missing_kwoa_py3": - python3 -m pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]" - - -Do not forget to clone astroid_ and install the last version:: - - - git clone https://github.com/PyCQA/astroid.git - - # From source - python3 astroid/setup.py build sdist - pip3 install astroid/dist/astroid*.tar.gz - - # Using an editable installation - cd astroid - python3 -m pip install -e . - - -For more detailed information, check the documentation. - -.. _here: https://pylint.pycqa.org/en/latest/user_guide/installation.html -.. _tox: https://tox.readthedocs.io/en/latest/ -.. _pytest: https://docs.pytest.org/en/latest/ -.. _pytest-cov: https://pypi.org/project/pytest-cov/ -.. _astroid: https://github.com/PyCQA/astroid - -License -------- - -pylint is, with a few exceptions listed below, `GPLv2 `_. - -The icon files are licensed under the `CC BY-SA 4.0 `_ license: - -- `doc/logo.png `_ -- `doc/logo.svg `_ - - diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/RECORD b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/RECORD deleted file mode 100644 index b4bae48e..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/RECORD +++ /dev/null @@ -1,187 +0,0 @@ -../../../bin/epylint,sha256=mNcLDzXWu1SSTPNRWQIfIU-t40UaOHc9m1BgAGLtlwA,264 -../../../bin/pylint,sha256=6FY-zQ-HVS65jH0lYQMhSN1zpKnBXSrDJVBJO2626IU,262 -../../../bin/pyreverse,sha256=S7IRsxsoggGz-agd-3fAu14H2WWp2k8fb_xJ_my_EXA,268 -../../../bin/symilar,sha256=eZk8N_ICOlhqAsKf7RiOb1n4GDZrOW9LvQ5FWIuglXc,264 -pylint-2.6.0.data/scripts/epylint,sha256=ebDphNeMoKus049k5MQbxN1JYsHUsOXZxws0Do6gCG0,51 -pylint-2.6.0.data/scripts/pylint,sha256=wXf1V2_-AB_S1uuYztSS90GiTeCkJ4eBOGEQ7CO2Nmc,53 -pylint-2.6.0.data/scripts/pyreverse,sha256=4UQf7-hfOAx6Ux8d5g0d2KIjpUPRMwFhBdsKsu0gWg0,59 -pylint-2.6.0.data/scripts/symilar,sha256=iz6DGtePyfs0haoFobDfsRsMjaFOizh7E3vsevB2Ipw,55 -pylint-2.6.0.dist-info/COPYING,sha256=-XsUCA3ouEkNYOs9Yg68QZlD4HeUZtHdDV1vaP4ZXc0,17984 -pylint-2.6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pylint-2.6.0.dist-info/METADATA,sha256=tyNZytHzEEwcJ9VzfKzbveXToNRzjOdN0XDpdJfsk14,6705 -pylint-2.6.0.dist-info/RECORD,, -pylint-2.6.0.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92 -pylint-2.6.0.dist-info/entry_points.txt,sha256=WUTwHM2ZcExO-VSvss18AMFsQL-XcWg6O3_MwobWfmw,137 -pylint-2.6.0.dist-info/top_level.txt,sha256=j6Z9i__pIuaiCka6Ul9YIy6yI5aw5QbCtldLvZlMksE,7 -pylint/__init__.py,sha256=v4P6u-dsxp2oq7QRVH29e7BT4M5bdn-8YZbwjebaWe0,1159 -pylint/__main__.py,sha256=HRja-2If7jX6FMF5dY7uMVUO2kJ3I0Y0uflK2ckDA5s,585 -pylint/__pkginfo__.py,sha256=3JpKkNXffks0hqvIVBZDhr5bPzHAOPBi-VWcCq7GtU4,4121 -pylint/__pycache__/__init__.cpython-38.pyc,, -pylint/__pycache__/__main__.cpython-38.pyc,, -pylint/__pycache__/__pkginfo__.cpython-38.pyc,, -pylint/__pycache__/constants.cpython-38.pyc,, -pylint/__pycache__/epylint.cpython-38.pyc,, -pylint/__pycache__/exceptions.cpython-38.pyc,, -pylint/__pycache__/graph.cpython-38.pyc,, -pylint/__pycache__/interfaces.cpython-38.pyc,, -pylint/__pycache__/testutils.cpython-38.pyc,, -pylint/checkers/__init__.py,sha256=Xs6vVoNtulCm3eLzOKZXzLydO3CkZoo-LCUi02V9DSw,2203 -pylint/checkers/__pycache__/__init__.cpython-38.pyc,, -pylint/checkers/__pycache__/async.cpython-38.pyc,, -pylint/checkers/__pycache__/base.cpython-38.pyc,, -pylint/checkers/__pycache__/base_checker.cpython-38.pyc,, -pylint/checkers/__pycache__/classes.cpython-38.pyc,, -pylint/checkers/__pycache__/design_analysis.cpython-38.pyc,, -pylint/checkers/__pycache__/exceptions.cpython-38.pyc,, -pylint/checkers/__pycache__/format.cpython-38.pyc,, -pylint/checkers/__pycache__/imports.cpython-38.pyc,, -pylint/checkers/__pycache__/logging.cpython-38.pyc,, -pylint/checkers/__pycache__/misc.cpython-38.pyc,, -pylint/checkers/__pycache__/newstyle.cpython-38.pyc,, -pylint/checkers/__pycache__/python3.cpython-38.pyc,, -pylint/checkers/__pycache__/raw_metrics.cpython-38.pyc,, -pylint/checkers/__pycache__/refactoring.cpython-38.pyc,, -pylint/checkers/__pycache__/similar.cpython-38.pyc,, -pylint/checkers/__pycache__/spelling.cpython-38.pyc,, -pylint/checkers/__pycache__/stdlib.cpython-38.pyc,, -pylint/checkers/__pycache__/strings.cpython-38.pyc,, -pylint/checkers/__pycache__/typecheck.cpython-38.pyc,, -pylint/checkers/__pycache__/utils.cpython-38.pyc,, -pylint/checkers/__pycache__/variables.cpython-38.pyc,, -pylint/checkers/async.py,sha256=JsT7Tz40BzExCxOM1lxOazq8a5U5Qt30NVH7skaVVeg,3524 -pylint/checkers/base.py,sha256=k6S26UCUdr2KhKibI4Py_DXZsVP72oEgJVQSbdu8m5c,96488 -pylint/checkers/base_checker.py,sha256=6EiWxqNjJ69sQYbLNobRY--GDByqH-HUfivDc2EUC6Y,7664 -pylint/checkers/classes.py,sha256=RAiGs_3bN7fLpSq9DE8jwVTfFpQzIEQ7sv5NrzUoTsw,79023 -pylint/checkers/design_analysis.py,sha256=CHrofelHlAVPMx_NzDlLAU4A7lh_F5tOTa47BSEiCBE,16861 -pylint/checkers/exceptions.py,sha256=28OsFP9Qka-WIJEBwSj0058REHMkCt7jTM7sLPVO4Q4,23729 -pylint/checkers/format.py,sha256=HMAD_0DRrLOLHV2vl6dzEpF96FocYlIxbc0EDxyvXGo,28135 -pylint/checkers/imports.py,sha256=XC9a9KhVg3wUT2bytUbDeoQPZX3DUX3Wn_ebD-21nvc,38230 -pylint/checkers/logging.py,sha256=t_EM5pASCXB4ZLpgVm1O4WEXCP08K8ZzyFCqSTfz33M,15919 -pylint/checkers/misc.py,sha256=gVe__qHnXK1RDHXXrByndQd6_VSnWnZcObWKNgViiqE,7241 -pylint/checkers/newstyle.py,sha256=BRTLrHos8vvfB5vnmK2q_XHrDHPlImM6e1ykybq_5_o,5067 -pylint/checkers/python3.py,sha256=qSnqN2HBpELbFDBJ6VOShoUoMyvWhvbHu7ln2vg9rAM,53095 -pylint/checkers/raw_metrics.py,sha256=bi52QkvDD8rBH1tM5wh15-T9KdAXeM_rrSzwdDFJ73s,4040 -pylint/checkers/refactoring.py,sha256=ToWYmRszGgmNfln_eqeqCh_KKjxCPpvhxLvtMtn75tQ,63239 -pylint/checkers/similar.py,sha256=xbPADFB8VPBu4XrVj1LBB1FOMQpg0jQyGJWCw16TXpc,15458 -pylint/checkers/spelling.py,sha256=Dx1ruls8wi0yIqMDb2kJ2kh2tO3_cAGieGDn8Y-dx8k,13867 -pylint/checkers/stdlib.py,sha256=-5laS4-VByRWyD5uJsP7ijHUELdLWT8o4v5FB_ptK44,17690 -pylint/checkers/strings.py,sha256=CIjSzGeyGbNbxsJ86UMKLHZKBtGIodOUMQsPyYV9_MU,38113 -pylint/checkers/typecheck.py,sha256=FgD4diwuE6OXtQBpyPV-8Xl4AFtsX5a5gpWzeMt4LQQ,71732 -pylint/checkers/utils.py,sha256=5j4dc1NEpZywEG1loQ2pe5qlFdJH2I9P1-mhjTEKrn8,45213 -pylint/checkers/variables.py,sha256=cDH63Hwj2l7_nejxVBsn7rtv5S7Bgm23vNWITVJBa48,80398 -pylint/config/__init__.py,sha256=3USGhpgN7m5H7VqsLPjOJsRyjIQswaUv5z1rY1dyBiM,4459 -pylint/config/__pycache__/__init__.cpython-38.pyc,, -pylint/config/__pycache__/configuration_mixin.cpython-38.pyc,, -pylint/config/__pycache__/find_default_config_files.cpython-38.pyc,, -pylint/config/__pycache__/man_help_formatter.cpython-38.pyc,, -pylint/config/__pycache__/option.cpython-38.pyc,, -pylint/config/__pycache__/option_manager_mixin.cpython-38.pyc,, -pylint/config/__pycache__/option_parser.cpython-38.pyc,, -pylint/config/__pycache__/options_provider_mixin.cpython-38.pyc,, -pylint/config/configuration_mixin.py,sha256=2gvNKg1LZBtlnAUqO2OOHFZvgdigfZLswAFO58CzO1Q,1105 -pylint/config/find_default_config_files.py,sha256=sPIxomIQUXvvh-11Ygc-NiBYIrK5wQO_7LMkzqxfo4Y,2103 -pylint/config/man_help_formatter.py,sha256=JZEeNKvjSpdYTY0jV5_PahKqSP8Ei489JH7Uk4oPkkI,3777 -pylint/config/option.py,sha256=jWXPFt3YCALhgmuo5T87TZQ5EbochLAGAj7nArllxrc,5406 -pylint/config/option_manager_mixin.py,sha256=Z2yMMhjb4oUOSuzs7xYYxN__F0Sa9hCha80DeqF2UD8,14470 -pylint/config/option_parser.py,sha256=7-PmG8r5i5N4r5tgRUq1A45sq_pRz8lFMtw33nRST4Y,1689 -pylint/config/options_provider_mixin.py,sha256=vXWVrsnz-zDLW6YlHflJTtvI_QqvqusajJy_YxK8iZg,4176 -pylint/constants.py,sha256=vnKjbOfqog3sjuSN48ZXO6VeQrb0sV43D028rVeZDss,1405 -pylint/epylint.py,sha256=kKt3on5YJw5vXLI9AeO9gIB3u9lH8fkE1ReGlyzPNJw,7240 -pylint/exceptions.py,sha256=WuVt9BlJW92g8fggqy7aCoC9GgSIy9AEpHsiCKo8psU,1153 -pylint/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pylint/extensions/__pycache__/__init__.cpython-38.pyc,, -pylint/extensions/__pycache__/_check_docs_utils.cpython-38.pyc,, -pylint/extensions/__pycache__/bad_builtin.cpython-38.pyc,, -pylint/extensions/__pycache__/broad_try_clause.cpython-38.pyc,, -pylint/extensions/__pycache__/check_docs.cpython-38.pyc,, -pylint/extensions/__pycache__/check_elif.cpython-38.pyc,, -pylint/extensions/__pycache__/comparetozero.cpython-38.pyc,, -pylint/extensions/__pycache__/docparams.cpython-38.pyc,, -pylint/extensions/__pycache__/docstyle.cpython-38.pyc,, -pylint/extensions/__pycache__/emptystring.cpython-38.pyc,, -pylint/extensions/__pycache__/mccabe.cpython-38.pyc,, -pylint/extensions/__pycache__/overlapping_exceptions.cpython-38.pyc,, -pylint/extensions/__pycache__/redefined_variable_type.cpython-38.pyc,, -pylint/extensions/_check_docs_utils.py,sha256=X-phX6z3Znthcuq4BpgMZR-3Z-cS3iRgIMHlwq4uIXM,23564 -pylint/extensions/bad_builtin.py,sha256=nCYJ4nGEvbTnB6AlPMx_IBjb2bWFu3rkz6ThW_pQ6Ac,2510 -pylint/extensions/broad_try_clause.py,sha256=nIOTZfOVGsM4fp50yyaes-z--iAlYvgQcbvlA_W5i3Q,2331 -pylint/extensions/check_docs.py,sha256=SJvB9OaaPeA5GsWZRofYuUlfP6u_Wny4Ugog0OqtzGs,796 -pylint/extensions/check_elif.py,sha256=rj3FgaXcCylZTb_PWraCCOnmzkPuA0hLc3CZo3lg8hA,2614 -pylint/extensions/comparetozero.py,sha256=MeVUIYTv4kFEHbBZHAjQXbIa1LbnHK9VncEoZKxHe5w,2469 -pylint/extensions/docparams.py,sha256=fCQC3z2gX6CbUCv6cGaIeF1ps_icrvIYI8Eu_ul32MY,20437 -pylint/extensions/docstyle.py,sha256=bG8V4n9fXjWrSyXl3ZKi5gNnVogEgcroJo9wxykKGEM,3035 -pylint/extensions/emptystring.py,sha256=kkk35STu_Bsm9Boi1sjVTCa7ZeB5duo3I1fbjWKjUfI,2568 -pylint/extensions/mccabe.py,sha256=7jupZPjE0a5SsfxhSj9O3al0j6vjR_J18q7cCSTzGLY,6278 -pylint/extensions/overlapping_exceptions.py,sha256=Qsi7qIF6sx36HYV8cjKjPcgYRZNPiFIg4NEcefjGFyg,3266 -pylint/extensions/redefined_variable_type.py,sha256=qopv8bgRcPOiQoa8c6btH0trTQEt2tCRm4sug6qOwjM,4333 -pylint/graph.py,sha256=jj1v2fqQrGAhjdPOLVAzOsqLFR9ce7LTVyyFKjaAhTQ,6528 -pylint/interfaces.py,sha256=jSpQ-c3PGqLZF7LsJue5gHz6IdYire9ki7cieG6xdfE,3235 -pylint/lint/__init__.py,sha256=FkrvfVY1gTb6syeGkvNDM37-0pXXOmR8qu0ig95CQ9M,4188 -pylint/lint/__pycache__/__init__.cpython-38.pyc,, -pylint/lint/__pycache__/check_parallel.cpython-38.pyc,, -pylint/lint/__pycache__/pylinter.cpython-38.pyc,, -pylint/lint/__pycache__/report_functions.cpython-38.pyc,, -pylint/lint/__pycache__/run.cpython-38.pyc,, -pylint/lint/__pycache__/utils.cpython-38.pyc,, -pylint/lint/check_parallel.py,sha256=Jov2r9_0_hjRBfOC0ZYSyU67dY99pv-idEIE5fBnN3I,3973 -pylint/lint/pylinter.py,sha256=ZRjQ7iSTbI6lC0HroM7urKdooqcfCpVN1ss05mjOzRo,45795 -pylint/lint/report_functions.py,sha256=4jB7bRHENFdvY4xXMamIC1VaQdrYdyp-629KujV-pI8,2750 -pylint/lint/run.py,sha256=lq3iu62kTYIIXXsHbDFnf8rIx7MxEMpKJ30fHNmYZA8,17223 -pylint/lint/utils.py,sha256=glQ5R9CNfpDL6Kj9lysnlUOOpOGuMP_sLA2gUpA1m2w,2308 -pylint/message/__init__.py,sha256=sgVx9YmL9b84Y6TgsfOKHJchXnxOd-EGV52wEKWLLe8,2807 -pylint/message/__pycache__/__init__.cpython-38.pyc,, -pylint/message/__pycache__/message.cpython-38.pyc,, -pylint/message/__pycache__/message_definition.cpython-38.pyc,, -pylint/message/__pycache__/message_definition_store.cpython-38.pyc,, -pylint/message/__pycache__/message_handler_mix_in.cpython-38.pyc,, -pylint/message/__pycache__/message_id_store.cpython-38.pyc,, -pylint/message/message.py,sha256=eJQ6x3SKMQpD6aLn4x2tYT4NSUy4qWzVhl_0Am5R5WI,1300 -pylint/message/message_definition.py,sha256=o7zckciMEunKoi3wz7U2m507HsXD4IeHuPJ-anURyi8,2993 -pylint/message/message_definition_store.py,sha256=aQi_4Z_tEw9lxQyn07-w_BapJLd04OcZIJ5A4tLgxho,3535 -pylint/message/message_handler_mix_in.py,sha256=BcHlarVGm-ySZOmMOKSmJ-jQlQhVXA6HYpFw4p1_ZYc,15208 -pylint/message/message_id_store.py,sha256=Nri4iRo9t5QefzJP9MU0phz66dBZ3ienVNRqQNQoDac,5291 -pylint/pyreverse/__init__.py,sha256=runafCn0veg0di-i8TztMGlKEJO3Qg01MICGqDgZ0c0,202 -pylint/pyreverse/__pycache__/__init__.cpython-38.pyc,, -pylint/pyreverse/__pycache__/diadefslib.cpython-38.pyc,, -pylint/pyreverse/__pycache__/diagrams.cpython-38.pyc,, -pylint/pyreverse/__pycache__/inspector.cpython-38.pyc,, -pylint/pyreverse/__pycache__/main.cpython-38.pyc,, -pylint/pyreverse/__pycache__/utils.cpython-38.pyc,, -pylint/pyreverse/__pycache__/vcgutils.cpython-38.pyc,, -pylint/pyreverse/__pycache__/writer.cpython-38.pyc,, -pylint/pyreverse/diadefslib.py,sha256=9y9COGVkaeWlMbuMh0PH0ka5FXuN5jvOjEZAPbtZAdI,8754 -pylint/pyreverse/diagrams.py,sha256=PAuxP25QXqEmQgFpJDHxCEKHo9EIpB7o8cYFITe3FGc,9035 -pylint/pyreverse/inspector.py,sha256=RyFmZ_8IEH59EpXOqkS1d3KsqTdn_LWu-_a3fNu08QU,12257 -pylint/pyreverse/main.py,sha256=FIrqeVfxM8fje0QprImOFLeiz4s7oawOMXoa5yJEPqA,6528 -pylint/pyreverse/utils.py,sha256=-pmBeypy9i6GRD4oBdaudBYCZfMoXXQUENWZBS9geU0,6351 -pylint/pyreverse/vcgutils.py,sha256=5IsM9m21JZ5n-1edmqi1EHFK2ZYy2IX1WzfI8Uoe4Ts,6584 -pylint/pyreverse/writer.py,sha256=10wgUZ-8ANHgCvI2c1ZkukcAeZ-dfbJ_MWL75MoRCuI,8003 -pylint/reporters/__init__.py,sha256=dVj9-p_ireGR0jF2qxsu54a-0H_jxDafNiMUUVuHWH4,1650 -pylint/reporters/__pycache__/__init__.cpython-38.pyc,, -pylint/reporters/__pycache__/base_reporter.cpython-38.pyc,, -pylint/reporters/__pycache__/collecting_reporter.cpython-38.pyc,, -pylint/reporters/__pycache__/json_reporter.cpython-38.pyc,, -pylint/reporters/__pycache__/reports_handler_mix_in.cpython-38.pyc,, -pylint/reporters/__pycache__/text.cpython-38.pyc,, -pylint/reporters/base_reporter.py,sha256=HilNSVW_QAG34uY73b01eLlK-RPMgA62O4gk19rVIm8,2031 -pylint/reporters/collecting_reporter.py,sha256=tFJ0rsTNz9h4C0U5lgbe1jlQAOy0Of0WLGrq2QO7Sug,478 -pylint/reporters/json_reporter.py,sha256=JzakpeEjYZVFjtkpjmiU_die-zSugOONpSb6UHW91Ls,1996 -pylint/reporters/reports_handler_mix_in.py,sha256=t4Ucmk5Wa2CagNbEbehlr1n6H-4zmRnrCEvI57qVuig,2704 -pylint/reporters/text.py,sha256=tAMiL676mppZonTqGGUK9EAXv9q7rT_Np8GE0L_phj4,8087 -pylint/reporters/ureports/__init__.py,sha256=UteHDRjY2qMHwLUpA3McgaBMTdQnMTKrVRZ5A_WZybA,3235 -pylint/reporters/ureports/__pycache__/__init__.cpython-38.pyc,, -pylint/reporters/ureports/__pycache__/nodes.cpython-38.pyc,, -pylint/reporters/ureports/__pycache__/text_writer.cpython-38.pyc,, -pylint/reporters/ureports/nodes.py,sha256=7ze_4YQHtNpx8wdsQHtU0sAMOSWVcIvaoKe4eVWnYJM,5193 -pylint/reporters/ureports/text_writer.py,sha256=SuKF0eKZcLvF457lXJyxFVk-M3epvAXCesKo6T2aBlU,3373 -pylint/testutils.py,sha256=bWQ0rsxptVTQRIEavbDahP_pzgy1Nbh4hYe5PicAu8w,20452 -pylint/utils/__init__.py,sha256=LR5PAyLJhLu7dDWCBkeCGN00MqPYz6pgkr_wFSrfqCA,2984 -pylint/utils/__pycache__/__init__.cpython-38.pyc,, -pylint/utils/__pycache__/ast_walker.cpython-38.pyc,, -pylint/utils/__pycache__/file_state.cpython-38.pyc,, -pylint/utils/__pycache__/pragma_parser.cpython-38.pyc,, -pylint/utils/__pycache__/utils.cpython-38.pyc,, -pylint/utils/ast_walker.py,sha256=6ewsiRTz1W4v9UFm-lXMZoBWEe8b89kZRrSN7bW3aiM,2907 -pylint/utils/file_state.py,sha256=zw-4J5JasNZPhmcTbDUwiqaXpPWCIpPdYizvyGlnvCo,5962 -pylint/utils/pragma_parser.py,sha256=FuAydaJb_O6RMbVVyZg83eACKVuWxurtc5n1Gxz6E3Q,4799 -pylint/utils/utils.py,sha256=ahZtvd-OXZfJA_4l9KWoBb5TIfx_6zHdKvdSqZeNtns,14497 diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/WHEEL b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/WHEEL deleted file mode 100644 index 83ff02e9..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/entry_points.txt deleted file mode 100644 index 063b5e45..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/entry_points.txt +++ /dev/null @@ -1,6 +0,0 @@ -[console_scripts] -epylint = pylint:run_epylint -pylint = pylint:run_pylint -pyreverse = pylint:run_pyreverse -symilar = pylint:run_symilar - diff --git a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/top_level.txt b/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/top_level.txt deleted file mode 100644 index 7fb0ea15..00000000 --- a/env/lib/python3.8/site-packages/pylint-2.6.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pylint diff --git a/env/lib/python3.8/site-packages/pylint/__init__.py b/env/lib/python3.8/site-packages/pylint/__init__.py deleted file mode 100644 index 8c475581..00000000 --- a/env/lib/python3.8/site-packages/pylint/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2008, 2012 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2014, 2016-2020 Claudiu Popa -# Copyright (c) 2014 Arun Persaud -# Copyright (c) 2015 Ionel Cristian Maries -# Copyright (c) 2018 Nick Drozd -# Copyright (c) 2020 Pierre Sassoulas - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -import sys - -from pylint.__pkginfo__ import version as __version__ - -# pylint: disable=import-outside-toplevel - - -def run_pylint(): - from pylint.lint import Run as PylintRun - - try: - PylintRun(sys.argv[1:]) - except KeyboardInterrupt: - sys.exit(1) - - -def run_epylint(): - from pylint.epylint import Run as EpylintRun - - EpylintRun() - - -def run_pyreverse(): - """run pyreverse""" - from pylint.pyreverse.main import Run as PyreverseRun - - PyreverseRun(sys.argv[1:]) - - -def run_symilar(): - """run symilar""" - from pylint.checkers.similar import Run as SimilarRun - - SimilarRun(sys.argv[1:]) diff --git a/env/lib/python3.8/site-packages/pylint/__main__.py b/env/lib/python3.8/site-packages/pylint/__main__.py deleted file mode 100644 index badb5002..00000000 --- a/env/lib/python3.8/site-packages/pylint/__main__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -#!/usr/bin/env python -import os -import sys - -import pylint - -# Strip out the current working directory from sys.path. -# Having the working directory in `sys.path` means that `pylint` might -# inadvertently import user code from modules having the same name as -# stdlib or pylint's own modules. -# CPython issue: https://bugs.python.org/issue33053 -if sys.path[0] == "" or sys.path[0] == os.getcwd(): - sys.path.pop(0) - -pylint.run_pylint() diff --git a/env/lib/python3.8/site-packages/pylint/__pkginfo__.py b/env/lib/python3.8/site-packages/pylint/__pkginfo__.py deleted file mode 100644 index 11e46003..00000000 --- a/env/lib/python3.8/site-packages/pylint/__pkginfo__.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2010 Julien Jehannet -# Copyright (c) 2013-2014 Google, Inc. -# Copyright (c) 2014-2020 Claudiu Popa -# Copyright (c) 2014 Brett Cannon -# Copyright (c) 2014 Ricardo Gemignani -# Copyright (c) 2014 Arun Persaud -# Copyright (c) 2015 Ionel Cristian Maries -# Copyright (c) 2016 Moises Lopez -# Copyright (c) 2016 Florian Bruhin -# Copyright (c) 2016 Jakub Wilk -# Copyright (c) 2017-2018 Hugo -# Copyright (c) 2018-2019 Ashley Whetter -# Copyright (c) 2018 ssolanki -# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> -# Copyright (c) 2019-2020 Ville Skyttä -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 Dan Hemberger <846186+hemberger@users.noreply.github.com> -# Copyright (c) 2019 jab -# Copyright (c) 2020 hippo91 -# Copyright (c) 2020 Damien Baty -# Copyright (c) 2020 Pierre Sassoulas - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -# pylint: disable=redefined-builtin,invalid-name -"""pylint packaging information""" - - -from os.path import join - -# For an official release, use dev_version = None -numversion = (2, 6, 0) -dev_version = None - -version = ".".join(str(num) for num in numversion) -if dev_version is not None: - version += "-dev" + str(dev_version) - -install_requires = [ - "astroid>=2.4.0,<=2.5", - "isort>=4.2.5,<6", - "mccabe>=0.6,<0.7", - "toml>=0.7.1", -] - -dependency_links = [] # type: ignore - -extras_require = {} -extras_require[':sys_platform=="win32"'] = ["colorama"] - -license = "GPL" -description = "python code static checker" -web = "https://github.com/PyCQA/pylint" -mailinglist = "mailto:code-quality@python.org" -project_urls = {"What's New": "https://pylint.pycqa.org/en/latest/whatsnew/"} -author = "Python Code Quality Authority" -author_email = "code-quality@python.org" - -classifiers = [ - "Development Status :: 6 - Mature", - "Environment :: Console", - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU General Public License (GPL)", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Debuggers", - "Topic :: Software Development :: Quality Assurance", - "Topic :: Software Development :: Testing", -] - - -long_desc = """\ - Pylint is a Python source code analyzer which looks for programming - errors, helps enforcing a coding standard and sniffs for some code - smells (as defined in Martin Fowler's Refactoring book) - . - Pylint can be seen as another PyChecker since nearly all tests you - can do with PyChecker can also be done with Pylint. However, Pylint - offers some more features, like checking length of lines of code, - checking if variable names are well-formed according to your coding - standard, or checking if declared interfaces are truly implemented, - and much more. - . - Additionally, it is possible to write plugins to add your own checks. - . - Pylint is shipped with "pyreverse" (UML diagram generator) - and "symilar" (an independent similarities checker).""" - -scripts = [ - join("bin", filename) for filename in ("pylint", "symilar", "epylint", "pyreverse") -] diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index ac69c3ab273bc30ff1b4ad62468e3285acc33f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1112 zcmb_b&2G~`5Z<+&#Q7_t55lg$XGdnvo-#6no{eFkw8-4#3esc)14m>p->`JtbcE8n4ONqh)KwrHWHA z(T4R$ad5GoVW}6`7)1h-(9eXD^T7qlt&cVmk+0T0a!Dz9OT+_*qb7Z8YI=mjc1?A2opp1WgVr_9`$%w*6_V?T;ii$MTG>E^ zvF8ML>YD%g43j7prgYhak8EKBh~CLM$PO4f3;3CWL$LJyliyQ-ubKR}D3IIW_A!6}L0ZU8k!0k^X-1K}MglHC z(1zOdk0FeU2^wndW@TIom|%~lb&E3eTS*=;9u(^0>*il*OK$S9(;1$DbcrhvkY79{IrB5G+AAe GbNUM*aacS6 diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/__pkginfo__.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/__pkginfo__.cpython-38.pyc deleted file mode 100644 index 833e697636c3c44422ca0650fac88bc4c58810aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2815 zcmbVOO>-MX6W*29mMuGu4Iz2?NHUl&3uGxIyh+N~E>aGJRE5M~0##E*sYcta)!^Nk z^~|n?w%`>0zgE@bcQ&P-3w(@*zw&;3)UnjZbG z|Np1n^Q)fsv+F$hTcgf<^w=M%0grp&LoN1`8n5{t)Oj5O9>CmpHJFFSw;tASdJp{X zeLjZ)1c!^}CeFbE&SUVvKj&TZ_#7-k6P92(3V0*(_=5EKBAkkRT!fWv4^HzYtnwvT zFCv}^d zR&7%2T;g?=CqH;*kyiW)-JwpfYcVvKX@%WLW<7(cw%uIGF2T%(mjXcHC9 z&xay=!?L?LD%vw;6)(g^cqE(@5!oedXtVB!#I3?nw>ZCFvdZ=xtdA?r>_$#Z8``5d z_jfz8n|O?|P7|caIv{g$%eJ=IRkq1KqK?7h?EC6i8m&qRn%dLK>KKcQw^fD;5NI2a zs6uoLr|Qty;@vwkL}kn2dk44KjWjj-nB+<9*4_K;7WvhPnC<8Nm`I#SZxG9^V*Or9 zlbMV1gR#vpajWhfu-mj_>b6x`abe%+h&+}!sXIbNxroZ$DlUpw{(0VMyi&Y&0wIc~ z6Nz0tnb@_HiCr(=Isvwl7Zs0-cb_hNJ4s`7ek@alTe&x->iWM~yg%L_7jJ&5Q}Q0^ zI?#h`Bn-}CU=}bpv7bkgi-^llm3u8 z%<9}waFz#FC_z-AVWXi8hb-3m&@wvZEPWhGO@_v3W7}+qacUX5EE~EQ6HbZypmVQ4 z7+~~bR>{Gj(qbtgmK!yhO)!ov+Ypuk4y2;Emx|7mA*}2JJ&MuLLH`5?lqTtnlF~kb zX*F4=IWr;@iuEbUASy;`gwm8y4bARV`G#5PPMtzw;xQ9(%v@5iY^?JpbBjT<5oMw$ zR=80STkZ4$IKJD2V{u8n`Y}Nk2?@Da84*jHF3l1@A`G=D`OUO5!c6HVGN*jE z8M*37jeucHY8px0z!Ajx;+jH4lQ57uQDU-Ok~oaV&ck<(`!Q`Q|Dk_A7P&_ zx$;Zl>MY~SbmYIpFze+ewtQZcwURGa?;c%TWXzW+x+oe3lA!X%SgWY#l#8bt}+?Krgu1^ zIi8_;o}~r8#2tQz=XjnM`10>IUFIu%^$ilsZ&%)-I(m)iD!f?aYkZwsJhO-?@(sGy zK)l57zCrx%YeLugC&Ct{z&{%!qlD-N$9+`3H-}tNyNp%lOvKWU!rA7byuVqwe|R)K z5BxCs4%{!F|MdOli?7Ph0e^Y;;Oon>Ju@oP^O*@STwt`oS3pZ`@*tQKc$wPney`Tt znPcscot`rNa1>Ez7=>pdOyCbyHWnjqm_)J4yz=7E568+9aSXmS@)9p7+X^=ot|{D8 zcwb>x;hmv=@53^{FyYkT$P$2$F3^j@A-TktAMJf*!K2i8= zK`h|?QS~^Qh^iFBSR_#>s$)N4v6x1(dK&uGDP(voCSJHDMGR6^MR-;X{G;mhJUNcS zZz_+f(oe(|#GQC!A%WNGRiRFqcwr(zDdjxo{xBIvlj)Psb*?sm4V$2N1I)QjZ=Thl z%c1tflZl9jVEi`1j;i80NYH&hLZa`a2mD^9H><^=fpy^3q7kN8%nzPIbrJWIpe1Gm*3&?Wu(;91x0D+`8WB5C28 zVY{7ngRb28I+49TU2SbQ+pPA3Tl>-NvG#V$U5H3?qthVxP}u*eudiA1uNyufBprxbxM%{ diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/epylint.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/epylint.cpython-38.pyc deleted file mode 100644 index eda086770ec43d0c01c7556ec3b277e77ffa6ce6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4969 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 IEC=@g0fkw|TmS$7 diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/exceptions.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index e912d990ab458588c4a482048843bb10d35d3099..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1331 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 diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/interfaces.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/interfaces.cpython-38.pyc deleted file mode 100644 index f1de50e91d534ad7f07e82dcc5cdf797e3a13037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3741 zcmbVP+j1Mn5#1X=5CB2al4IR$k8L>?QZ|r^^Pt!+7ad+KlvS{clI#SoWNWcA05)3e z!ZQQ1h@zgTf5->q$$yc`XY6a9@(X!MPS4`9pr}Ol7H2s3?m2zBr}1QKt7_r9|JQ%` zf2&*8KdDpvJaqO@)ZbBYt7mbWJFz`>dX8-ghr8V4rJ-}-^jzWcGT%VUL#x6!(JG-; zB~ca|L$6o)(&7!i{oLZ)nAzkzeD}H4t77yuehs77#O8(DtD%3L zzmERvqK1AQ{a^4m(0{}9x6r@AZ=!$G^c(2k;~xO~j}N>1hqHIT3uF={L)H(J;4Dp8 zlnjKV!(!=G&SS(IN+zRRX#m_}&4@KQUC9Iwe1~}Y?tvwFgKesOIUWt1^ zwuDI^6#)cO2?wDL@0$$6VV<<+Lr=$Xit-lB0qwZlffRGiLbXj} zgx1@nLK#)X_8iAHV{7=5^HMSRevSt4H4c2?K6A8v?r2B5130f@=gz=>=A1hR)}O9F zbG3Kwp4%6WylY$BePsP`H#hR^&&NVfWx}+a3Kk6*pk+g1d+tE&-Z(hx3lI&w&dtQ& zWadUqwggaB89v&(M7d>#vWCBcS^2)X_2VP3Yhx&MptS@g)Z*yOizB78(%erYrKbH{ zl$W_sDBD~f->W@cN$*`>wgq1nw;OiZuGm!+Npm3$7e6Ay9*Sb9 ziq4X|O3$NEiSSn9W$=3=t9159B77?3Z1i{(DTcqm#Dx_qAF?FX4B;jkCU97tGJrd! z$RQAGPDh9wfDvdTlofR)$AJdezY@BiFj}c%FIhABKaL82gVO~~K3#IvMAa~74?7)2;fN(7C&(m_ zh`r=nGB{;}C>DkoYjJ^?dX?q>NH)gHNJPvnTQ!>(-kOhnpy=h$2+D@CA#I?C4n_&^ zyl9z5yoG-v7%z9{{AfCoL3Fk;Usb@6;L93w@$(pYfUyN*ZWVxNtuN~~OIMoeeQYmC zSXt>kOzhFwM0&(dSJKGOw$WDSar#sw3oCunS-f^dD=G3*om(j|kdZf&nKW%?6vc4O`n%hHp)hA`MbBx4CB0|m{;sSXSW=A|n;2y(K zDaFC_%o&f=Bo5BzS*KzM!@&dzsL2dLj(}knN#m%S9)Js^|B}CL+q9Y33rTU|BAs$<$8!GTxmBm`HY$~^o%&8~ Kr@B+#ss9%&pN-`J diff --git a/env/lib/python3.8/site-packages/pylint/__pycache__/testutils.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/__pycache__/testutils.cpython-38.pyc deleted file mode 100644 index 370b1e0a63043424f70e8cdf349bc2fc266c2a6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20756 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 YWRSP4kCD$h_VmQm+#b|*9&q;lKYYVSe*gdg diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__init__.py b/env/lib/python3.8/site-packages/pylint/checkers/__init__.py deleted file mode 100644 index 921a54a2..00000000 --- a/env/lib/python3.8/site-packages/pylint/checkers/__init__.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2013-2014 Google, Inc. -# Copyright (c) 2013 buck@yelp.com -# Copyright (c) 2014-2018, 2020 Claudiu Popa -# Copyright (c) 2014 Brett Cannon -# Copyright (c) 2014 Arun Persaud -# Copyright (c) 2015 Ionel Cristian Maries -# Copyright (c) 2016 Moises Lopez -# Copyright (c) 2017-2018 Bryce Guinta -# Copyright (c) 2018-2019 Pierre Sassoulas -# Copyright (c) 2018 ssolanki -# Copyright (c) 2019 Bruno P. Kinoshita - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -"""utilities methods and classes for checkers - -Base id of standard checkers (used in msg and report ids): -01: base -02: classes -03: format -04: import -05: misc -06: variables -07: exceptions -08: similar -09: design_analysis -10: newstyle -11: typecheck -12: logging -13: string_format -14: string_constant -15: stdlib -16: python3 -17: refactoring -18-50: not yet used: reserved for future internal checkers. -51-99: perhaps used: reserved for external checkers - -The raw_metrics checker has no number associated since it doesn't emit any -messages nor reports. XXX not true, emit a 07 report ! - -""" - -from pylint.checkers.base_checker import BaseChecker, BaseTokenChecker -from pylint.utils import register_plugins - - -def table_lines_from_stats(stats, _, columns): - """get values listed in from and , - and return a formated list of values, designed to be given to a - ureport.Table object - """ - lines = [] - for m_type in columns: - new = stats[m_type] - new = "%.3f" % new if isinstance(new, float) else str(new) - lines += (m_type.replace("_", " "), new, "NC", "NC") - return lines - - -def initialize(linter): - """initialize linter with checkers in this package """ - register_plugins(linter, __path__[0]) - - -__all__ = ("BaseChecker", "BaseTokenChecker", "initialize") diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index a433dab34de6c16c372dce80df340f96c700ff17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1602 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 Y|I7qHF2mpg-T_`F$DxBYoYgP>0T{*o`2YX_ diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base.cpython-38.pyc deleted file mode 100644 index f7b52edadce2ceb2c5d3a3b711b2ddeb5247c7d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63728 zcmc${3zS^PdEeRZ?&*18@O}^^8xTlfK+F&TDT<;%h0U z-NbQ561l(sSNGoTo(J{VJz0=_=iaKiRdv7m>Z`B5S3N&ET2Arr(LeR;wcovwPW>A_ z^#2>?;R$|0A)88hscOngdztxkHEn-0)r|ekRSdoW^W76TkN^g*xk6haZlskM#bCuR=&EYk-NRu+jb{i zeV@0zy3gBDy{~a!W8Z9gHdDR7vESSIM!I^SQJS0JcaYx${0`0Ls*~QX>Qo~=_h9v~ zcUR-^wp8_qx7)k>N~U_$yT`kizYjGYZoJ>CczbAj@9ESVY43gBKJUKE**7w?Y43h- zKj{aQ{)Ke)5pTjf=sn;a@+RNPRX;$xQ?&aie;?%U2ff49$Gjun(NCwUAMzgZ9_H^c z@BQ8*{C(W}fcGeWk9!~V9^>zay$^ZE`1^$Sc=d#L-1{*1Cq18DpYon~EA5@|PJTLH zJ?)+HPLp%SJL8?@?^*9j?aR}jQ0tz=Do@_ z{;%%UEoa)h;*hG^>`qG@qXfho|cc&DP}$otyKG z>6uJl)w&nSIK?kG%4I1vr(c?1hF^A#Uyd|de5<^a-kGBQ%=Fvku&~hfuFp5Z{0y+^ z@Mpdr1Yv3RdTU1DBEJE=y)Xxa{jgN`FJE71v^rtwwYuM|U*gRT_DW6p%}duijc};h zns2rm6qqQ4BhNg0x;A~{nKQNXPrewAoqBfq!o~jQr%znC(0d*~edg?m=b!E?vH6sh zIC1gf`Ew_qzv!wNIrZ!_&(&TyabA_aoe8ru^FcV&sxLHZotuk|w^RNeK(ajh;Fb15 z zs=MXmpLqFWFMB5@tFP!ze;?SlR_eih-MbI0E_`sQR+~Clt4-|dKE6iwCyySwwN#61 zR^jOWWv|w2&|a^s`+C&C^xGr;K49nHr_23Z!eXuFwPzUNjNb^0Gwp@N=6vJ52e@w} zZD4IU4^UZ)U$BWwDV@ud)9$}qI`eKW>ns1i?SP(QBF^^)bpOf$or&{TjOV7oA*yLK zSEVtQcddYS?UlZfJh&>;jiU{oAxrI*mtTLthV7p9$~vr=_9uYdnn0f<QC+i?4bx3`?J>v?e;;?>LnF^FW^210RO}~z*XM*z}0#a z6a9v5K#WVtd0FF9N+()3jdZW#P_n#uN=<6-(@EWCGjm6rO=h~AnL7A(#(#ix|Bx>C z=+axQjIzCtv_H!)5Vw=cbT`Ef^_I=)iTnz>>hGuQ`iq}9vA6gIIWDC%3!YLY@?p8R z%v6UG3Kf=nQztCBIrI4A%b7iocSm7E;2?v}lvcNH@xEY6{7ZL3ZSiKUeraav#K}|7G&=R} zaNh$E!e0p1yc)`U31!X6kU5zOiC7!t$~CX3)_(b^LEqu>r7<%B1|$ zJi$O`;fBMU*PP+1lHEKB2PV3iPu}WgKK{z8Zsy}|ZsVq@ZjRlegI;PWy)E@qQ5U

    S{155=m@bxYSyssM)5cPCH-b2@MpI|o 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 aeVd&v^lpCE8@A_NA}sX}(jN7(ckbWAK8uI| diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base_checker.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/base_checker.cpython-38.pyc deleted file mode 100644 index 1badd73f9adcb8b6534a8965e817fc8e92bf45c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6589 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 GgZ~5gRMU?D diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-38.pyc deleted file mode 100644 index d8f2172ece3e871303dabc5ddb52aac73d852fb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11330 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 diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/format.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/format.cpython-38.pyc deleted file mode 100644 index e9f69e8b6d7e44b96545a5e0629e4de2e5b2e028..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16005 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 RTmQ&+GCKHcG4=1n{{`Gd!TA6H diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/imports.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/imports.cpython-38.pyc deleted file mode 100644 index 0bf20fcf3e37ec1f47013ccf7dac797f30994a85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25328 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 M#(v03|2_790fL5>PXGV_ diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/logging.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/logging.cpython-38.pyc deleted file mode 100644 index 5605f59c50961d5d72d617ee0e9a1d9f2f612a9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11674 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 S&O+9rXKBmB+~U#ZxBmi`aj%*H diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/python3.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/python3.cpython-38.pyc deleted file mode 100644 index cdc63d3d9cd3597a1cd812013dc0f00dbf7e2e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34955 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 diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/spelling.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/spelling.cpython-38.pyc deleted file mode 100644 index 7fe9b011040b0676ce6b473609eb894a29f3551f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9714 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 b!X|1H_|cVR`3K3Qzf9ry#P^l&E8G7Evk;ru diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/strings.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/strings.cpython-38.pyc deleted file mode 100644 index a423a2eecf9bd256b3f11c7875cb666483861a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22106 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 R=Fb=#sYGgIWber2{|BAbkgos$ diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/typecheck.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/typecheck.cpython-38.pyc deleted file mode 100644 index 9f768ac1e6491bfb026ff1f2cbf061dcc414711a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41888 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 diff --git a/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/variables.cpython-38.pyc b/env/lib/python3.8/site-packages/pylint/checkers/__pycache__/variables.cpython-38.pyc deleted file mode 100644 index 9f91d32c0acc1433b01af06b3ac1f4913c52b330..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45304 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 diff --git a/env/lib/python3.8/site-packages/pylint/checkers/async.py b/env/lib/python3.8/site-packages/pylint/checkers/async.py deleted file mode 100644 index 1b581c0f..00000000 --- a/env/lib/python3.8/site-packages/pylint/checkers/async.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (c) 2015-2018, 2020 Claudiu Popa -# Copyright (c) 2017 Derek Gustafson -# Copyright (c) 2019 Pierre Sassoulas - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -"""Checker for anything related to the async protocol (PEP 492).""" - -import sys - -import astroid -from astroid import bases, exceptions - -from pylint import checkers, interfaces, utils -from pylint.checkers import utils as checker_utils -from pylint.checkers.utils import decorated_with - - -class AsyncChecker(checkers.BaseChecker): - __implements__ = interfaces.IAstroidChecker - name = "async" - msgs = { - "E1700": ( - "Yield inside async function", - "yield-inside-async-function", - "Used when an `yield` or `yield from` statement is " - "found inside an async function.", - {"minversion": (3, 5)}, - ), - "E1701": ( - "Async context manager '%s' doesn't implement __aenter__ and __aexit__.", - "not-async-context-manager", - "Used when an async context manager is used with an object " - "that does not implement the async context management protocol.", - {"minversion": (3, 5)}, - ), - } - - def open(self): - self._ignore_mixin_members = utils.get_global_option( - self, "ignore-mixin-members" - ) - self._async_generators = ["contextlib.asynccontextmanager"] - - @checker_utils.check_messages("yield-inside-async-function") - def visit_asyncfunctiondef(self, node): - for child in node.nodes_of_class(astroid.Yield): - if child.scope() is node and ( - sys.version_info[:2] == (3, 5) or isinstance(child, astroid.YieldFrom) - ): - self.add_message("yield-inside-async-function", node=child) - - @checker_utils.check_messages("not-async-context-manager") - def visit_asyncwith(self, node): - for ctx_mgr, _ in node.items: - inferred = checker_utils.safe_infer(ctx_mgr) - if inferred is None or inferred is astroid.Uninferable: - continue - - if isinstance(inferred, bases.AsyncGenerator): - # Check if we are dealing with a function decorated - # with contextlib.asynccontextmanager. - if decorated_with(inferred.parent, self._async_generators): - continue - else: - try: - inferred.getattr("__aenter__") - inferred.getattr("__aexit__") - except exceptions.NotFoundError: - if isinstance(inferred, astroid.Instance): - # If we do not know the bases of this class, - # just skip it. - if not checker_utils.has_known_bases(inferred): - continue - # Just ignore mixin classes. - if self._ignore_mixin_members: - if inferred.name[-5:].lower() == "mixin": - continue - else: - continue - - self.add_message( - "not-async-context-manager", node=node, args=(inferred.name,) - ) - - -def register(linter): - """required method to auto register this checker""" - linter.register_checker(AsyncChecker(linter)) diff --git a/env/lib/python3.8/site-packages/pylint/checkers/base.py b/env/lib/python3.8/site-packages/pylint/checkers/base.py deleted file mode 100644 index d830a68b..00000000 --- a/env/lib/python3.8/site-packages/pylint/checkers/base.py +++ /dev/null @@ -1,2507 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2006-2016 LOGILAB S.A. (Paris, FRANCE) -# Copyright (c) 2010 Daniel Harding -# Copyright (c) 2012-2014 Google, Inc. -# Copyright (c) 2013-2020 Claudiu Popa -# Copyright (c) 2014 Brett Cannon -# Copyright (c) 2014 Arun Persaud -# Copyright (c) 2015 Nick Bastin -# Copyright (c) 2015 Michael Kefeder -# Copyright (c) 2015 Dmitry Pribysh -# Copyright (c) 2015 Stephane Wirtel -# Copyright (c) 2015 Cosmin Poieana -# Copyright (c) 2015 Florian Bruhin -# Copyright (c) 2015 Radu Ciorba -# Copyright (c) 2015 Ionel Cristian Maries -# Copyright (c) 2016, 2019 Ashley Whetter -# Copyright (c) 2016, 2018 Jakub Wilk -# Copyright (c) 2016-2017 Łukasz Rogalski -# Copyright (c) 2016 Glenn Matthews -# Copyright (c) 2016 Elias Dorneles -# Copyright (c) 2016 Yannack -# Copyright (c) 2016 Alex Jurkiewicz -# Copyright (c) 2017 Pierre Sassoulas -# Copyright (c) 2017, 2019 hippo91 -# Copyright (c) 2017 danields -# Copyright (c) 2017 Jacques Kvam -# Copyright (c) 2017 ttenhoeve-aa -# Copyright (c) 2018-2019 Nick Drozd -# Copyright (c) 2018-2019 Ville Skyttä -# Copyright (c) 2018 Sergei Lebedev <185856+superbobry@users.noreply.github.com> -# Copyright (c) 2018 Lucas Cimon -# Copyright (c) 2018 ssolanki -# Copyright (c) 2018 Natalie Serebryakova -# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> -# Copyright (c) 2018 SergeyKosarchuk -# Copyright (c) 2018 Steven M. Vascellaro -# Copyright (c) 2018 Mike Frysinger -# Copyright (c) 2018 Chris Lamb -# Copyright (c) 2018 glmdgrielson <32415403+glmdgrielson@users.noreply.github.com> -# Copyright (c) 2019 Daniel Draper -# Copyright (c) 2019 Hugo van Kemenade -# Copyright (c) 2019 Pierre Sassoulas -# Copyright (c) 2019 Niko Wenselowski -# Copyright (c) 2019 Nikita Sobolev -# Copyright (c) 2019 Oisín Moran -# Copyright (c) 2019 Fantix King -# Copyright (c) 2020 Damien Baty -# Copyright (c) 2020 Ram Rachum -# Copyright (c) 2020 Anthony Sottile -# Copyright (c) 2020 bernie gray -# Copyright (c) 2020 Gabriel R Sezefredo -# Copyright (c) 2020 Benny -# Copyright (c) 2020 Anubhav <35621759+anubh-v@users.noreply.github.com> - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/master/COPYING - -"""basic checker for Python code""" -import builtins -import collections -import itertools -import re -import sys -from typing import Pattern - -import astroid -import astroid.bases -import astroid.scoped_nodes -from astroid.arguments import CallSite - -from pylint import checkers, exceptions, interfaces -from pylint import utils as lint_utils -from pylint.checkers import utils -from pylint.checkers.utils import ( - is_overload_stub, - is_property_deleter, - is_property_setter, -) -from pylint.reporters.ureports import nodes as reporter_nodes - - -class NamingStyle: - # It may seem counterintuitive that single naming style - # has multiple "accepted" forms of regular expressions, - # but we need to special-case stuff like dunder names - # in method names. - CLASS_NAME_RGX = None # type: Pattern[str] - MOD_NAME_RGX = None # type: Pattern[str] - CONST_NAME_RGX = None # type: Pattern[str] - COMP_VAR_RGX = None # type: Pattern[str] - DEFAULT_NAME_RGX = None # type: Pattern[str] - CLASS_ATTRIBUTE_RGX = None # type: Pattern[str] - - @classmethod - def get_regex(cls, name_type): - return { - "module": cls.MOD_NAME_RGX, - "const": cls.CONST_NAME_RGX, - "class": cls.CLASS_NAME_RGX, - "function": cls.DEFAULT_NAME_RGX, - "method": cls.DEFAULT_NAME_RGX, - "attr": cls.DEFAULT_NAME_RGX, - "argument": cls.DEFAULT_NAME_RGX, - "variable": cls.DEFAULT_NAME_RGX, - "class_attribute": cls.CLASS_ATTRIBUTE_RGX, - "inlinevar": cls.COMP_VAR_RGX, - }[name_type] - - -class SnakeCaseStyle(NamingStyle): - """Regex rules for snake_case naming style.""" - - CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]+$") - MOD_NAME_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]*$") - CONST_NAME_RGX = re.compile(r"([^\W\dA-Z][^\WA-Z]*|__.*__)$") - COMP_VAR_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]*$") - DEFAULT_NAME_RGX = re.compile( - r"([^\W\dA-Z][^\WA-Z]{2,}|_[^\WA-Z]*|__[^\WA-Z\d_][^\WA-Z]+__)$" - ) - CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\WA-Z]{2,}|__.*__)$") - - -class CamelCaseStyle(NamingStyle): - """Regex rules for camelCase naming style.""" - - CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\W_]+$") - MOD_NAME_RGX = re.compile(r"[^\W\dA-Z][^\W_]*$") - CONST_NAME_RGX = re.compile(r"([^\W\dA-Z][^\W_]*|__.*__)$") - COMP_VAR_RGX = re.compile(r"[^\W\dA-Z][^\W_]*$") - DEFAULT_NAME_RGX = re.compile(r"([^\W\dA-Z][^\W_]{2,}|__[^\W\dA-Z_]\w+__)$") - CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\W_]{2,}|__.*__)$") - - -class PascalCaseStyle(NamingStyle): - """Regex rules for PascalCase naming style.""" - - CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\W_]+$") - MOD_NAME_RGX = re.compile(r"[^\W\da-z][^\W_]+$") - CONST_NAME_RGX = re.compile(r"([^\W\da-z][^\W_]*|__.*__)$") - COMP_VAR_RGX = re.compile(r"[^\W\da-z][^\W_]+$") - DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\W_]{2,}|__[^\W\dA-Z_]\w+__)$") - CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\W_]{2,}$") - - -class UpperCaseStyle(NamingStyle): - """Regex rules for UPPER_CASE naming style.""" - - CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\Wa-z]+$") - MOD_NAME_RGX = re.compile(r"[^\W\da-z][^\Wa-z]+$") - CONST_NAME_RGX = re.compile(r"([^\W\da-z][^\Wa-z]*|__.*__)$") - COMP_VAR_RGX = re.compile(r"[^\W\da-z][^\Wa-z]+$") - DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\Wa-z]{2,}|__[^\W\dA-Z_]\w+__)$") - CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\Wa-z]{2,}$") - - -class AnyStyle(NamingStyle): - @classmethod - def get_regex(cls, name_type): - return re.compile(".*") - - -NAMING_STYLES = { - "snake_case": SnakeCaseStyle, - "camelCase": CamelCaseStyle, - "PascalCase": PascalCaseStyle, - "UPPER_CASE": UpperCaseStyle, - "any": AnyStyle, -} - -# do not require a doc string on private/system methods -NO_REQUIRED_DOC_RGX = re.compile("^_") -REVERSED_PROTOCOL_METHOD = "__reversed__" -SEQUENCE_PROTOCOL_METHODS = ("__getitem__", "__len__") -REVERSED_METHODS = (SEQUENCE_PROTOCOL_METHODS, (REVERSED_PROTOCOL_METHOD,)) -TYPECHECK_COMPARISON_OPERATORS = frozenset(("is", "is not", "==", "!=")) -LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set) -UNITTEST_CASE = "unittest.case" -BUILTINS = builtins.__name__ -TYPE_QNAME = "%s.type" % BUILTINS -ABC_METACLASSES = {"_py_abc.ABCMeta", "abc.ABCMeta"} # Python 3.7+, - -# Name categories that are always consistent with all naming conventions. -EXEMPT_NAME_CATEGORIES = {"exempt", "ignore"} - -# A mapping from qname -> symbol, to be used when generating messages -# about dangerous default values as arguments -DEFAULT_ARGUMENT_SYMBOLS = dict( - zip( - [".".join([BUILTINS, x]) for x in ("set", "dict", "list")], - ["set()", "{}", "[]"], - ), - **{ - x: "%s()" % x - for x in ( - "collections.deque", - "collections.ChainMap", - "collections.Counter", - "collections.OrderedDict", - "collections.defaultdict", - "collections.UserDict", - "collections.UserList", - ) - }, -) -REVERSED_COMPS = {"<": ">", "<=": ">=", ">": "<", ">=": "<="} -COMPARISON_OPERATORS = frozenset(("==", "!=", "<", ">", "<=", ">=")) -# List of methods which can be redefined -REDEFINABLE_METHODS = frozenset(("__module__",)) -TYPING_FORWARD_REF_QNAME = "typing.ForwardRef" - - -def _redefines_import(node): - """ Detect that the given node (AssignName) is inside an - exception handler and redefines an import from the tryexcept body. - Returns True if the node redefines an import, False otherwise. - """ - current = node - while current and not isinstance(current.parent, astroid.ExceptHandler): - current = current.parent - if not current or not utils.error_of_type(current.parent, ImportError): - return False - try_block = current.parent.parent - for import_node in try_block.nodes_of_class((astroid.ImportFrom, astroid.Import)): - for name, alias in import_node.names: - if alias: - if alias == node.name: - return True - elif name == node.name: - return True - return False - - -def in_loop(node): - """return True if the node is inside a kind of for loop""" - parent = node.parent - while parent is not None: - if isinstance( - parent, - ( - astroid.For, - astroid.ListComp, - astroid.SetComp, - astroid.DictComp, - astroid.GeneratorExp, - ), - ): - return True - parent = parent.parent - return False - - -def in_nested_list(nested_list, obj): - """return true if the object is an element of or of a nested - list - """ - for elmt in nested_list: - if isinstance(elmt, (list, tuple)): - if in_nested_list(elmt, obj): - return True - elif elmt == obj: - return True - return False - - -def _get_break_loop_node(break_node): - """ - Returns the loop node that holds the break node in arguments. - - Args: - break_node (astroid.Break): the break node of interest. - - Returns: - astroid.For or astroid.While: the loop node holding the break node. - """ - loop_nodes = (astroid.For, astroid.While) - parent = break_node.parent - while not isinstance(parent, loop_nodes) or break_node in getattr( - parent, "orelse", [] - ): - break_node = parent - parent = parent.parent - if parent is None: - break - return parent - - -def _loop_exits_early(loop): - """ - Returns true if a loop may ends up in a break statement. - - Args: - loop (astroid.For, astroid.While): the loop node inspected. - - Returns: - bool: True if the loop may ends up in a break statement, False otherwise. - """ - loop_nodes = (astroid.For, astroid.While) - definition_nodes = (astroid.FunctionDef, astroid.ClassDef) - inner_loop_nodes = [ - _node - for _node in loop.nodes_of_class(loop_nodes, skip_klass=definition_nodes) - if _node != loop - ] - return any( - _node - for _node in loop.nodes_of_class(astroid.Break, skip_klass=definition_nodes) - if _get_break_loop_node(_node) not in inner_loop_nodes - ) - - -def _is_multi_naming_match(match, node_type, confidence): - return ( - match is not None - and match.lastgroup is not None - and match.lastgroup not in EXEMPT_NAME_CATEGORIES - and (node_type != "method" or confidence != interfaces.INFERENCE_FAILURE) - ) - - -BUILTIN_PROPERTY = "builtins.property" - - -def _get_properties(config): - """Returns a tuple of property classes and names. - - Property classes are fully qualified, such as 'abc.abstractproperty' and - property names are the actual names, such as 'abstract_property'. - """ - property_classes = {BUILTIN_PROPERTY} - property_names = set() # Not returning 'property', it has its own check. - if config is not None: - property_classes.update(config.property_classes) - property_names.update( - prop.rsplit(".", 1)[-1] for prop in config.property_classes - ) - return property_classes, property_names - - -def _determine_function_name_type(node: astroid.FunctionDef, config=None): - """Determine the name type whose regex the a function's name should match. - - :param node: A function node. - :param config: Configuration from which to pull additional property classes. - :type config: :class:`optparse.Values` - - :returns: One of ('function', 'method', 'attr') - :rtype: str - """ - property_classes, property_names = _get_properties(config) - if not node.is_method(): - return "function" - - if is_property_setter(node) or is_property_deleter(node): - # If the function is decorated using the prop_method.{setter,getter} - # form, treat it like an attribute as well. - return "attr" - - if node.decorators: - decorators = node.decorators.nodes - else: - decorators = [] - for decorator in decorators: - # If the function is a property (decorated with @property - # or @abc.abstractproperty), the name type is 'attr'. - if isinstance(decorator, astroid.Name) or ( - isinstance(decorator, astroid.Attribute) - and decorator.attrname in property_names - ): - inferred = utils.safe_infer(decorator) - if ( - inferred - and hasattr(inferred, "qname") - and inferred.qname() in property_classes - ): - return "attr" - return "method" - - -def _has_abstract_methods(node): - """ - Determine if the given `node` has abstract methods. - - The methods should be made abstract by decorating them - with `abc` decorators. - """ - return len(utils.unimplemented_abstract_methods(node)) > 0 - - -def report_by_type_stats(sect, stats, _): - """make a report of - - * percentage of different types documented - * percentage of different types with a bad name - """ - # percentage of different types documented and/or with a bad name - nice_stats = {} - for node_type in ("module", "class", "method", "function"): - try: - total = stats[node_type] - except KeyError as e: - raise exceptions.EmptyReportError() from e - nice_stats[node_type] = {} - if total != 0: - try: - documented = total - stats["undocumented_" + node_type] - percent = (documented * 100.0) / total - nice_stats[node_type]["percent_documented"] = "%.2f" % percent - except KeyError: - nice_stats[node_type]["percent_documented"] = "NC" - try: - percent = (stats["badname_" + node_type] * 100.0) / total - nice_stats[node_type]["percent_badname"] = "%.2f" % percent - except KeyError: - nice_stats[node_type]["percent_badname"] = "NC" - lines = ("type", "number", "old number", "difference", "%documented", "%badname") - for node_type in ("module", "class", "method", "function"): - new = stats[node_type] - lines += ( - node_type, - str(new), - "NC", - "NC", - nice_stats[node_type].get("percent_documented", "0"), - nice_stats[node_type].get("percent_badname", "0"), - ) - sect.append(reporter_nodes.Table(children=lines, cols=6, rheaders=1)) - - -def redefined_by_decorator(node): - """return True if the object is a method redefined via decorator. - - For example: - @property - def x(self): return self._x - @x.setter - def x(self, value): self._x = value - """ - if node.decorators: - for decorator in node.decorators.nodes: - if ( - isinstance(decorator, astroid.Attribute) - and getattr(decorator.expr, "name", None) == node.name - ): - return True - return False - - -class _BasicChecker(checkers.BaseChecker): - __implements__ = interfaces.IAstroidChecker - name = "basic" - - -class BasicErrorChecker(_BasicChecker): - msgs = { - "E0100": ( - "__init__ method is a generator", - "init-is-generator", - "Used when the special class method __init__ is turned into a " - "generator by a yield in its body.", - ), - "E0101": ( - "Explicit return in __init__", - "return-in-init", - "Used when the special class method __init__ has an explicit " - "return value.", - ), - "E0102": ( - "%s already defined line %s", - "function-redefined", - "Used when a function / class / method is redefined.", - ), - "E0103": ( - "%r not properly in loop", - "not-in-loop", - "Used when break or continue keywords are used outside a loop.", - ), - "E0104": ( - "Return outside function", - "return-outside-function", - 'Used when a "return" statement is found outside a function or method.', - ), - "E0105": ( - "Yield outside function", - "yield-outside-function", - 'Used when a "yield" statement is found outside a function or method.', - ), - "E0106": ( - "Return with argument inside generator", - "return-arg-in-generator", - 'Used when a "return" statement with an argument is found ' - "outside in a generator function or method (e.g. with some " - '"yield" statements).', - {"maxversion": (3, 3)}, - ), - "E0107": ( - "Use of the non-existent %s operator", - "nonexistent-operator", - "Used when you attempt to use the C-style pre-increment or " - "pre-decrement operator -- and ++, which doesn't exist in Python.", - ), - "E0108": ( - "Duplicate argument name %s in function definition", - "duplicate-argument-name", - "Duplicate argument names in function definitions are syntax errors.", - ), - "E0110": ( - "Abstract class %r with abstract methods instantiated", - "abstract-class-instantiated", - "Used when an abstract class with `abc.ABCMeta` as metaclass " - "has abstract methods and is instantiated.", - ), - "W0120": ( - "Else clause on loop without a break statement", - "useless-else-on-loop", - "Loops should only have an else clause if they can exit early " - "with a break statement, otherwise the statements under else " - "should be on the same scope as the loop itself.", - ), - "E0112": ( - "More than one starred expression in assignment", - "too-many-star-expressions", - "Emitted when there are more than one starred " - "expressions (`*x`) in an assignment. This is a SyntaxError.", - ), - "E0113": ( - "Starred assignment target must be in a list or tuple", - "invalid-star-assignment-target", - "Emitted when a star expression is used as a starred assignment target.", - ), - "E0114": ( - "Can use starred expression only in assignment target", - "star-needs-assignment-target", - "Emitted when a star expression is not used in an assignment target.", - ), - "E0115": ( - "Name %r is nonlocal and global", - "nonlocal-and-global", - "Emitted when a name is both nonlocal and global.", - ), - "E0116": ( - "'continue' not supported inside 'finally' clause", - "continue-in-finally", - "Emitted when the `continue` keyword is found " - "inside a finally clause, which is a SyntaxError.", - {"maxversion": (3, 8)}, - ), - "E0117": ( - "nonlocal name %s found without binding", - "nonlocal-without-binding", - "Emitted when a nonlocal variable does not have an attached " - "name somewhere in the parent scopes", - ), - "E0118": ( - "Name %r is used prior to global declaration", - "used-prior-global-declaration", - "Emitted when a name is used prior a global declaration, " - "which results in an error since Python 3.6.", - {"minversion": (3, 6)}, - ), - } - - @utils.check_messages("function-redefined") - def visit_classdef(self, node): - self._check_redefinition("class", node) - - def _too_many_starred_for_tuple(self, assign_tuple): - starred_count = 0 - for elem in assign_tuple.itered(): - if isinstance(elem, astroid.Tuple): - return self._too_many_starred_for_tuple(elem) - if isinstance(elem, astroid.Starred): - starred_count += 1 - return starred_count > 1 - - @utils.check_messages("too-many-star-expressions", "invalid-star-assignment-target") - def visit_assign(self, node): - # Check *a, *b = ... - assign_target = node.targets[0] - # Check *a = b - if isinstance(node.targets[0], astroid.Starred): - self.add_message("invalid-star-assignment-target", node=node) - - if not isinstance(assign_target, astroid.Tuple): - return - if self._too_many_starred_for_tuple(assign_target): - self.add_message("too-many-star-expressions", node=node) - - @utils.check_messages("star-needs-assignment-target") - def visit_starred(self, node): - """Check that a Starred expression is used in an assignment target.""" - if isinstance(node.parent, astroid.Call): - # f(*args) is converted to Call(args=[Starred]), so ignore - # them for this check. - return - if isinstance( - node.parent, (astroid.List, astroid.Tuple, astroid.Set, astroid.Dict) - ): - # PEP 448 unpacking. - return - - stmt = node.statement() - if not isinstance(stmt, astroid.Assign): - return - - if stmt.value is node or stmt.value.parent_of(node): - self.add_message("star-needs-assignment-target", node=node) - - @utils.check_messages( - "init-is-generator", - "return-in-init", - "function-redefined", - "return-arg-in-generator", - "duplicate-argument-name", - "nonlocal-and-global", - "used-prior-global-declaration", - ) - def visit_functiondef(self, node): - self._check_nonlocal_and_global(node) - self._check_name_used_prior_global(node) - if not redefined_by_decorator( - node - ) and not utils.is_registered_in_singledispatch_function(node): - self._check_redefinition(node.is_method() and "method" or "function", node) - # checks for max returns, branch, return in __init__ - returns = node.nodes_of_class( - astroid.Return, skip_klass=(astroid.FunctionDef, astroid.ClassDef) - ) - if node.is_method() and node.name == "__init__": - if node.is_generator(): - self.add_message("init-is-generator", node=node) - else: - values = [r.value for r in returns] - # Are we returning anything but None from constructors - if any(v for v in values if not utils.is_none(v)): - self.add_message("return-in-init", node=node) - # Check for duplicate names by clustering args with same name for detailed report - arg_clusters = collections.defaultdict(list) - arguments = filter(None, [node.args.args, node.args.kwonlyargs]) - - for arg in itertools.chain.from_iterable(arguments): - arg_clusters[arg.name].append(arg) - - # provide detailed report about each repeated argument - for argument_duplicates in arg_clusters.values(): - if len(argument_duplicates) != 1: - for argument in argument_duplicates: - self.add_message( - "duplicate-argument-name", - line=argument.lineno, - node=argument, - args=(argument.name,), - ) - - visit_asyncfunctiondef = visit_functiondef - - def _check_name_used_prior_global(self, node): - - scope_globals = { - name: child - for child in node.nodes_of_class(astroid.Global) - for name in child.names - if child.scope() is node - } - - if not scope_globals: - return - - for node_name in node.nodes_of_class(astroid.Name): - if node_name.scope() is not node: - continue - - name = node_name.name - corresponding_global = scope_globals.get(name) - if not corresponding_global: - continue - - global_lineno = corresponding_global.fromlineno - if global_lineno and global_lineno > node_name.fromlineno: - self.add_message( - "used-prior-global-declaration", node=node_name, args=(name,) - ) - - def _check_nonlocal_and_global(self, node): - """Check that a name is both nonlocal and global.""" - - def same_scope(current): - return current.scope() is node - - from_iter = itertools.chain.from_iterable - nonlocals = set( - from_iter( - child.names - for child in node.nodes_of_class(astroid.Nonlocal) - if same_scope(child) - ) - ) - - if not nonlocals: - return - - global_vars = set( - from_iter( - child.names - for child in node.nodes_of_class(astroid.Global) - if same_scope(child) - ) - ) - for name in nonlocals.intersection(global_vars): - self.add_message("nonlocal-and-global", args=(name,), node=node) - - @utils.check_messages("return-outside-function") - def visit_return(self, node): - if not isinstance(node.frame(), astroid.FunctionDef): - self.add_message("return-outside-function", node=node) - - @utils.check_messages("yield-outside-function") - def visit_yield(self, node): - self._check_yield_outside_func(node) - - @utils.check_messages("yield-outside-function") - def visit_yieldfrom(self, node): - self._check_yield_outside_func(node) - - @utils.check_messages("not-in-loop", "continue-in-finally") - def visit_continue(self, node): - self._check_in_loop(node, "continue") - - @utils.check_messages("not-in-loop") - def visit_break(self, node): - self._check_in_loop(node, "break") - - @utils.check_messages("useless-else-on-loop") - def visit_for(self, node): - self._check_else_on_loop(node) - - @utils.check_messages("useless-else-on-loop") - def visit_while(self, node): - self._check_else_on_loop(node) - - @utils.check_messages("nonexistent-operator") - def visit_unaryop(self, node): - """check use of the non-existent ++ and -- operator operator""" - if ( - (node.op in "+-") - and isinstance(node.operand, astroid.UnaryOp) - and (node.operand.op == node.op) - ): - self.add_message("nonexistent-operator", node=node, args=node.op * 2) - - def _check_nonlocal_without_binding(self, node, name): - current_scope = node.scope() - while True: - if current_scope.parent is None: - break - - if not isinstance(current_scope, (astroid.ClassDef, astroid.FunctionDef)): - self.add_message("nonlocal-without-binding", args=(name,), node=node) - return - - if name not in current_scope.locals: - current_scope = current_scope.parent.scope() - continue - - # Okay, found it. - return - - if not isinstance(current_scope, astroid.FunctionDef): - self.add_message("nonlocal-without-binding", args=(name,), node=node) - - @utils.check_messages("nonlocal-without-binding") - def visit_nonlocal(self, node): - for name in node.names: - self._check_nonlocal_without_binding(node, name) - - @utils.check_messages("abstract-class-instantiated") - def visit_call(self, node): - """ Check instantiating abstract class with - abc.ABCMeta as metaclass. - """ - try: - for inferred in node.func.infer(): - self._check_inferred_class_is_abstract(inferred, node) - except astroid.InferenceError: - return - - def _check_inferred_class_is_abstract(self, inferred, node): - if not isinstance(inferred, astroid.ClassDef): - return - - klass = utils.node_frame_class(node) - if klass is inferred: - # Don't emit the warning if the class is instantiated - # in its own body or if the call is not an instance - # creation. If the class is instantiated into its own - # body, we're expecting that it knows what it is doing. - return - - # __init__ was called - abstract_methods = _has_abstract_methods(inferred) - - if not abstract_methods: - return - - metaclass = inferred.metaclass() - - if metaclass is None: - # Python 3.4 has `abc.ABC`, which won't be detected - # by ClassNode.metaclass() - for ancestor in inferred.ancestors(): - if ancestor.qname() == "abc.ABC": - self.add_message( - "abstract-class-instantiated", args=(inferred.name,), node=node - ) - break - - return - - if metaclass.qname() in ABC_METACLASSES: - self.add_message( - "abstract-class-instantiated", args=(inferred.name,), node=node - ) - - def _check_yield_outside_func(self, node): - if not isinstance(node.frame(), (astroid.FunctionDef, astroid.Lambda)): - self.add_message("yield-outside-function", node=node) - - def _check_else_on_loop(self, node): - """Check that any loop with an else clause has a break statement.""" - if node.orelse and not _loop_exits_early(node): - self.add_message( - "useless-else-on-loop", - node=node, - # This is not optimal, but the line previous - # to the first statement in the else clause - # will usually be the one that contains the else:. - line=node.orelse[0].lineno - 1, - ) - - def _check_in_loop(self, node, node_name): - """check that a node is inside a for or while loop""" - _node = node.parent - while _node: - if isinstance(_node, (astroid.For, astroid.While)): - if node not in _node.orelse: - return - - if isinstance(_node, (astroid.ClassDef, astroid.FunctionDef)): - break - if ( - isinstance(_node, astroid.TryFinally) - and node in _node.finalbody - and isinstance(node, astroid.Continue) - ): - self.add_message("continue-in-finally", node=node) - - _node = _node.parent - - self.add_message("not-in-loop", node=node, args=node_name) - - def _check_redefinition(self, redeftype, node): - """check for redefinition of a function / method / class name""" - parent_frame = node.parent.frame() - - # Ignore function stubs created for type information - redefinitions = parent_frame.locals[node.name] - defined_self = next( - (local for local in redefinitions if not utils.is_overload_stub(local)), - node, - ) - if defined_self is not node and not astroid.are_exclusive(node, defined_self): - # Additional checks for methods which are not considered - # redefined, since they are already part of the base API. - if ( - isinstance(parent_frame, astroid.ClassDef) - and node.name in REDEFINABLE_METHODS - ): - return - - # Skip typing.overload() functions. - if utils.is_overload_stub(node): - return - - # Exempt functions redefined on a condition. - if isinstance(node.parent, astroid.If): - # Exempt "if not " cases - if ( - isinstance(node.parent.test, astroid.UnaryOp) - and node.parent.test.op == "not" - and isinstance(node.parent.test.operand, astroid.Name) - and node.parent.test.operand.name == node.name - ): - return - - # Exempt "if is not None" cases - # pylint: disable=too-many-boolean-expressions - if ( - isinstance(node.parent.test, astroid.Compare) - and isinstance(node.parent.test.left, astroid.Name) - and node.parent.test.left.name == node.name - and node.parent.test.ops[0][0] == "is" - and isinstance(node.parent.test.ops[0][1], astroid.Const) - and node.parent.test.ops[0][1].value is None - ): - return - - # Check if we have forward references for this node. - try: - redefinition_index = redefinitions.index(node) - except ValueError: - pass - else: - for redefinition in redefinitions[:redefinition_index]: - inferred = utils.safe_infer(redefinition) - if ( - inferred - and isinstance(inferred, astroid.Instance) - and inferred.qname() == TYPING_FORWARD_REF_QNAME - ): - return - - dummy_variables_rgx = lint_utils.get_global_option( - self, "dummy-variables-rgx", default=None - ) - if dummy_variables_rgx and dummy_variables_rgx.match(node.name): - return - self.add_message( - "function-redefined", - node=node, - args=(redeftype, defined_self.fromlineno), - ) - - -class BasicChecker(_BasicChecker): - """checks for : - * doc strings - * number of arguments, local variables, branches, returns and statements in - functions, methods - * required module attributes - * dangerous default values as arguments - * redefinition of function / method / class - * uses of the global statement - """ - - __implements__ = interfaces.IAstroidChecker - - name = "basic" - msgs = { - "W0101": ( - "Unreachable code", - "unreachable", - 'Used when there is some code behind a "return" or "raise" ' - "statement, which will never be accessed.", - ), - "W0102": ( - "Dangerous default value %s as argument", - "dangerous-default-value", - "Used when a mutable value as list or dictionary is detected in " - "a default value for an argument.", - ), - "W0104": ( - "Statement seems to have no effect", - "pointless-statement", - "Used when a statement doesn't have (or at least seems to) any effect.", - ), - "W0105": ( - "String statement has no effect", - "pointless-string-statement", - "Used when a string is used as a statement (which of course " - "has no effect). This is a particular case of W0104 with its " - "own message so you can easily disable it if you're using " - "those strings as documentation, instead of comments.", - ), - "W0106": ( - 'Expression "%s" is assigned to nothing', - "expression-not-assigned", - "Used when an expression that is not a function call is assigned " - "to nothing. Probably something else was intended.", - ), - "W0108": ( - "Lambda may not be necessary", - "unnecessary-lambda", - "Used when the body of a lambda expression is a function call " - "on the same argument list as the lambda itself; such lambda " - "expressions are in all but a few cases replaceable with the " - "function being called in the body of the lambda.", - ), - "W0109": ( - "Duplicate key %r in dictionary", - "duplicate-key", - "Used when a dictionary expression binds the same key multiple times.", - ), - "W0122": ( - "Use of exec", - "exec-used", - 'Used when you use the "exec" statement (function for Python ' - "3), to discourage its usage. That doesn't " - "mean you cannot use it !", - ), - "W0123": ( - "Use of eval", - "eval-used", - 'Used when you use the "eval" function, to discourage its ' - "usage. Consider using `ast.literal_eval` for safely evaluating " - "strings containing Python expressions " - "from untrusted sources. ", - ), - "W0150": ( - "%s statement in finally block may swallow exception", - "lost-exception", - "Used when a break or a return statement is found inside the " - "finally clause of a try...finally block: the exceptions raised " - "in the try clause will be silently swallowed instead of being " - "re-raised.", - ), - "W0199": ( - "Assert called on a 2-item-tuple. Did you mean 'assert x,y'?", - "assert-on-tuple", - "A call of assert on a tuple will always evaluate to true if " - "the tuple is not empty, and will always evaluate to false if " - "it is.", - ), - "W0124": ( - 'Following "as" with another context manager looks like a tuple.', - "confusing-with-statement", - "Emitted when a `with` statement component returns multiple values " - "and uses name binding with `as` only for a part of those values, " - "as in with ctx() as a, b. This can be misleading, since it's not " - "clear if the context manager returns a tuple or if the node without " - "a name binding is another context manager.", - ), - "W0125": ( - "Using a conditional statement with a constant value", - "using-constant-test", - "Emitted when a conditional statement (If or ternary if) " - "uses a constant value for its test. This might not be what " - "the user intended to do.", - ), - "W0126": ( - "Using a conditional statement with potentially wrong function or method call due to missing parentheses", - "missing-parentheses-for-call-in-test", - "Emitted when a conditional statement (If or ternary if) " - "seems to wrongly call a function due to missing parentheses", - ), - "W0127": ( - "Assigning the same variable %r to itself", - "self-assigning-variable", - "Emitted when we detect that a variable is assigned to itself", - ), - "W0128": ( - "Redeclared variable %r in assignment", - "redeclared-assigned-name", - "Emitted when we detect that a variable was redeclared in the same assignment.", - ), - "E0111": ( - "The first reversed() argument is not a sequence", - "bad-reversed-sequence", - "Used when the first argument to reversed() builtin " - "isn't a sequence (does not implement __reversed__, " - "nor __getitem__ and __len__", - ), - "E0119": ( - "format function is not called on str", - "misplaced-format-function", - "Emitted when format function is not called on str object. " - 'e.g doing print("value: {}").format(123) instead of ' - 'print("value: {}".format(123)). This might not be what the user ' - "intended to do.", - ), - "W0129": ( - "Assert statement has a string literal as its first argument. The assert will %s fail.", - "assert-on-string-literal", - "Used when an assert statement has a string literal as its first argument, which will " - "cause the assert to always pass.", - ), - } - - reports = (("RP0101", "Statistics by type", report_by_type_stats),) - - def __init__(self, linter): - _BasicChecker.__init__(self, linter) - self.stats = None - self._tryfinallys = None - - def open(self): - """initialize visit variables and statistics - """ - self._tryfinallys = [] - self.stats = self.linter.add_stats(module=0, function=0, method=0, class_=0) - - @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") - def visit_if(self, node): - self._check_using_constant_test(node, node.test) - - @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") - def visit_ifexp(self, node): - self._check_using_constant_test(node, node.test) - - @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") - def visit_comprehension(self, node): - if node.ifs: - for if_test in node.ifs: - self._check_using_constant_test(node, if_test) - - def _check_using_constant_test(self, node, test): - const_nodes = ( - astroid.Module, - astroid.scoped_nodes.GeneratorExp, - astroid.Lambda, - astroid.FunctionDef, - astroid.ClassDef, - astroid.bases.Generator, - astroid.UnboundMethod, - astroid.BoundMethod, - astroid.Module, - ) - structs = (astroid.Dict, astroid.Tuple, astroid.Set) - - # These nodes are excepted, since they are not constant - # values, requiring a computation to happen. - except_nodes = ( - astroid.Call, - astroid.BinOp, - astroid.BoolOp, - astroid.UnaryOp, - astroid.Subscript, - ) - inferred = None - emit = isinstance(test, (astroid.Const,) + structs + const_nodes) - if not isinstance(test, except_nodes): - inferred = utils.safe_infer(test) - - if emit: - self.add_message("using-constant-test", node=node) - elif isinstance(inferred, const_nodes): - # If the constant node is a FunctionDef or Lambda then - #  it may be a illicit function call due to missing parentheses - call_inferred = None - try: - if isinstance(inferred, astroid.FunctionDef): - call_inferred = inferred.infer_call_result() - elif isinstance(inferred, astroid.Lambda): - call_inferred = inferred.infer_call_result(node) - except astroid.InferenceError: - call_inferred = None - if call_inferred: - try: - for inf_call in call_inferred: - if inf_call != astroid.Uninferable: - self.add_message( - "missing-parentheses-for-call-in-test", node=node - ) - break - except astroid.InferenceError: - pass - self.add_message("using-constant-test", node=node) - - def visit_module(self, _): - """check module name, docstring and required arguments - """ - self.stats["module"] += 1 - - def visit_classdef(self, node): # pylint: disable=unused-argument - """check module name, docstring and redefinition - increment branch counter - """ - self.stats["class"] += 1 - - @utils.check_messages( - "pointless-statement", "pointless-string-statement", "expression-not-assigned" - ) - def visit_expr(self, node): - """Check for various kind of statements without effect""" - expr = node.value - if isinstance(expr, astroid.Const) and isinstance(expr.value, str): - # treat string statement in a separated message - # Handle PEP-257 attribute docstrings. - # An attribute docstring is defined as being a string right after - # an assignment at the module level, class level or __init__ level. - scope = expr.scope() - if isinstance( - scope, (astroid.ClassDef, astroid.Module, astroid.FunctionDef) - ): - if isinstance(scope, astroid.FunctionDef) and scope.name != "__init__": - pass - else: - sibling = expr.previous_sibling() - if ( - sibling is not None - and sibling.scope() is scope - and isinstance(sibling, (astroid.Assign, astroid.AnnAssign)) - ): - return - self.add_message("pointless-string-statement", node=node) - return - - # Ignore if this is : - # * a direct function call - # * the unique child of a try/except body - # * a yield statement - # * an ellipsis (which can be used on Python 3 instead of pass) - # warn W0106 if we have any underlying function call (we can't predict - # side effects), else pointless-statement - if ( - isinstance( - expr, (astroid.Yield, astroid.Await, astroid.Ellipsis, astroid.Call) - ) - or ( - isinstance(node.parent, astroid.TryExcept) - and node.parent.body == [node] - ) - or (isinstance(expr, astroid.Const) and expr.value is Ellipsis) - ): - return - if any(expr.nodes_of_class(astroid.Call)): - self.add_message( - "expression-not-assigned", node=node, args=expr.as_string() - ) - else: - self.add_message("pointless-statement", node=node) - - @staticmethod - def _filter_vararg(node, call_args): - # Return the arguments for the given call which are - # not passed as vararg. - for arg in call_args: - if isinstance(arg, astroid.Starred): - if ( - isinstance(arg.value, astroid.Name) - and arg.value.name != node.args.vararg - ): - yield arg - else: - yield arg - - @staticmethod - def _has_variadic_argument(args, variadic_name): - if not args: - return True - for arg in args: - if isinstance(arg.value, astroid.Name): - if arg.value.name != variadic_name: - return True - else: - return True - return False - - @utils.check_messages("unnecessary-lambda") - def visit_lambda(self, node): - """check whether or not the lambda is suspicious - """ - # if the body of the lambda is a call expression with the same - # argument list as the lambda itself, then the lambda is - # possibly unnecessary and at least suspicious. - if node.args.defaults: - # If the arguments of the lambda include defaults, then a - # judgment cannot be made because there is no way to check - # that the defaults defined by the lambda are the same as - # the defaults defined by the function called in the body - # of the lambda. - return - call = node.body - if not isinstance(call, astroid.Call): - # The body of the lambda must be a function call expression - # for the lambda to be unnecessary. - return - if isinstance(node.body.func, astroid.Attribute) and isinstance( - node.body.func.expr, astroid.Call - ): - # Chained call, the intermediate call might - # return something else (but we don't check that, yet). - return - - call_site = CallSite.from_call(call) - ordinary_args = list(node.args.args) - new_call_args = list(self._filter_vararg(node, call.args)) - if node.args.kwarg: - if self._has_variadic_argument(call.kwargs, node.args.kwarg): - return - - if node.args.vararg: - if self._has_variadic_argument(call.starargs, node.args.vararg): - return - elif call.starargs: - return - - if call.keywords: - # Look for additional keyword arguments that are not part - # of the lambda's signature - lambda_kwargs = {keyword.name for keyword in node.args.defaults} - if len(lambda_kwargs) != len(call_site.keyword_arguments): - # Different lengths, so probably not identical - return - if set(call_site.keyword_arguments).difference(lambda_kwargs): - return - - # The "ordinary" arguments must be in a correspondence such that: - # ordinary_args[i].name == call.args[i].name. - if len(ordinary_args) != len(new_call_args): - return - for arg, passed_arg in zip(ordinary_args, new_call_args): - if not isinstance(passed_arg, astroid.Name): - return - if arg.name != passed_arg.name: - return - - self.add_message("unnecessary-lambda", line=node.fromlineno, node=node) - - @utils.check_messages("dangerous-default-value") - def visit_functiondef(self, node): - """check function name, docstring, arguments, redefinition, - variable names, max locals - """ - self.stats["method" if node.is_method() else "function"] += 1 - self._check_dangerous_default(node) - - visit_asyncfunctiondef = visit_functiondef - - def _check_dangerous_default(self, node): - # check for dangerous default values as arguments - is_iterable = lambda n: isinstance(n, (astroid.List, astroid.Set, astroid.Dict)) - defaults = node.args.defaults or [] + node.args.kw_defaults or [] - for default in defaults: - if not default: - continue - try: - value = next(default.infer()) - except astroid.InferenceError: - continue - - if ( - isinstance(value, astroid.Instance) - and value.qname() in DEFAULT_ARGUMENT_SYMBOLS - ): - - if value is default: - msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()] - elif isinstance(value, astroid.Instance) or is_iterable(value): - # We are here in the following situation(s): - # * a dict/set/list/tuple call which wasn't inferred - # to a syntax node ({}, () etc.). This can happen - # when the arguments are invalid or unknown to - # the inference. - # * a variable from somewhere else, which turns out to be a list - # or a dict. - if is_iterable(default): - msg = value.pytype() - elif isinstance(default, astroid.Call): - msg = "%s() (%s)" % (value.name, value.qname()) - else: - msg = "%s (%s)" % (default.as_string(), value.qname()) - else: - # this argument is a name - msg = "%s (%s)" % ( - default.as_string(), - DEFAULT_ARGUMENT_SYMBOLS[value.qname()], - ) - self.add_message("dangerous-default-value", node=node, args=(msg,)) - - @utils.check_messages("unreachable", "lost-exception") - def visit_return(self, node): - """1 - check is the node has a right sibling (if so, that's some - unreachable code) - 2 - check is the node is inside the finally clause of a try...finally - block - """ - self._check_unreachable(node) - # Is it inside final body of a try...finally bloc ? - self._check_not_in_finally(node, "return", (astroid.FunctionDef,)) - - @utils.check_messages("unreachable") - def visit_continue(self, node): - """check is the node has a right sibling (if so, that's some unreachable - code) - """ - self._check_unreachable(node) - - @utils.check_messages("unreachable", "lost-exception") - def visit_break(self, node): - """1 - check is the node has a right sibling (if so, that's some - unreachable code) - 2 - check is the node is inside the finally clause of a try...finally - block - """ - # 1 - Is it right sibling ? - self._check_unreachable(node) - # 2 - Is it inside final body of a try...finally bloc ? - self._check_not_in_finally(node, "break", (astroid.For, astroid.While)) - - @utils.check_messages("unreachable") - def visit_raise(self, node): - """check if the node has a right sibling (if so, that's some unreachable - code) - """ - self._check_unreachable(node) - - @utils.check_messages("exec-used") - def visit_exec(self, node): - """just print a warning on exec statements""" - self.add_message("exec-used", node=node) - - def _check_misplaced_format_function(self, call_node): - if not isinstance(call_node.func, astroid.Attribute): - return - if call_node.func.attrname != "format": - return - - expr = utils.safe_infer(call_node.func.expr) - if expr is astroid.Uninferable: - return - if not expr: - # we are doubtful on inferred type of node, so here just check if format - # was called on print() - call_expr = call_node.func.expr - if not isinstance(call_expr, astroid.Call): - return - if ( - isinstance(call_expr.func, astroid.Name) - and call_expr.func.name == "print" - ): - self.add_message("misplaced-format-function", node=call_node) - - @utils.check_messages( - "eval-used", "exec-used", "bad-reversed-sequence", "misplaced-format-function" - ) - def visit_call(self, node): - """visit a Call node -> check if this is not a blacklisted builtin - call and check for * or ** use - """ - self._check_misplaced_format_function(node) - if isinstance(node.func, astroid.Name): - name = node.func.name - # ignore the name if it's not a builtin (i.e. not defined in the - # locals nor globals scope) - if not (name in node.frame() or name in node.root()): - if name == "exec": - self.add_message("exec-used", node=node) - elif name == "reversed": - self._check_reversed(node) - elif name == "eval": - self.add_message("eval-used", node=node) - - @utils.check_messages("assert-on-tuple", "assert-on-string-literal") - def visit_assert(self, node): - """check whether assert is used on a tuple or string literal.""" - if ( - node.fail is None - and isinstance(node.test, astroid.Tuple) - and len(node.test.elts) == 2 - ): - self.add_message("assert-on-tuple", node=node) - - if isinstance(node.test, astroid.Const) and isinstance(node.test.value, str): - if node.test.value: - when = "never" - else: - when = "always" - self.add_message("assert-on-string-literal", node=node, args=(when,)) - - @utils.check_messages("duplicate-key") - def visit_dict(self, node): - """check duplicate key in dictionary""" - keys = set() - for k, _ in node.items: - if isinstance(k, astroid.Const): - key = k.value - if key in keys: - self.add_message("duplicate-key", node=node, args=key) - keys.add(key) - - def visit_tryfinally(self, node): - """update try...finally flag""" - self._tryfinallys.append(node) - - def leave_tryfinally(self, node): # pylint: disable=unused-argument - """update try...finally flag""" - self._tryfinallys.pop() - - def _check_unreachable(self, node): - """check unreachable code""" - unreach_stmt = node.next_sibling() - if unreach_stmt is not None: - self.add_message("unreachable", node=unreach_stmt) - - def _check_not_in_finally(self, node, node_name, breaker_classes=()): - """check that a node is not inside a finally clause of a - try...finally statement. - If we found before a try...finally bloc a parent which its type is - in breaker_classes, we skip the whole check.""" - # if self._tryfinallys is empty, we're not an in try...finally block - if not self._tryfinallys: - return - # the node could be a grand-grand...-children of the try...finally - _parent = node.parent - _node = node - while _parent and not isinstance(_parent, breaker_classes): - if hasattr(_parent, "finalbody") and _node in _parent.finalbody: - self.add_message("lost-exception", node=node, args=node_name) - return - _node = _parent - _parent = _node.parent - - def _check_reversed(self, node): - """ check that the argument to `reversed` is a sequence """ - try: - argument = utils.safe_infer(utils.get_argument_from_call(node, position=0)) - except utils.NoSuchArgumentError: - pass - else: - if argument is astroid.Uninferable: - return - if argument is None: - # Nothing was inferred. - # Try to see if we have iter(). - if isinstance(node.args[0], astroid.Call): - try: - func = next(node.args[0].func.infer()) - except astroid.InferenceError: - return - if getattr( - func, "name", None - ) == "iter" and utils.is_builtin_object(func): - self.add_message("bad-reversed-sequence", node=node) - return - - if isinstance(argument, (astroid.List, astroid.Tuple)): - return - - if isinstance(argument, astroid.Instance): - if argument._proxied.name == "dict" and utils.is_builtin_object( - argument._proxied - ): - self.add_message("bad-reversed-sequence", node=node) - return - if any( - ancestor.name == "dict" and utils.is_builtin_object(ancestor) - for ancestor in argument._proxied.ancestors() - ): - # Mappings aren't accepted by reversed(), unless - # they provide explicitly a __reversed__ method. - try: - argument.locals[REVERSED_PROTOCOL_METHOD] - except KeyError: - self.add_message("bad-reversed-sequence", node=node) - return - - if hasattr(argument, "getattr"): - # everything else is not a proper sequence for reversed() - for methods in REVERSED_METHODS: - for meth in methods: - try: - argument.getattr(meth) - except astroid.NotFoundError: - break - else: - break - else: - self.add_message("bad-reversed-sequence", node=node) - else: - self.add_message("bad-reversed-sequence", node=node) - - @utils.check_messages("confusing-with-statement") - def visit_with(self, node): - # a "with" statement with multiple managers corresponds - # to one AST "With" node with multiple items - pairs = node.items - if pairs: - for prev_pair, pair in zip(pairs, pairs[1:]): - if isinstance(prev_pair[1], astroid.AssignName) and ( - pair[1] is None and not isinstance(pair[0], astroid.Call) - ): - # Don't emit a message if the second is a function call - # there's no way that can be mistaken for a name assignment. - # If the line number doesn't match - # we assume it's a nested "with". - self.add_message("confusing-with-statement", node=node) - - def _check_self_assigning_variable(self, node): - # Detect assigning to the same variable. - - scope = node.scope() - scope_locals = scope.locals - - rhs_names = [] - targets = node.targets - if isinstance(targets[0], astroid.Tuple): - if len(targets) != 1: - # A complex assignment, so bail out early. - return - targets = targets[0].elts - if len(targets) == 1: - # Unpacking a variable into the same name. - return - - if isinstance(node.value, astroid.Name): - if len(targets) != 1: - return - rhs_names = [node.value] - elif isinstance(node.value, astroid.Tuple): - rhs_count = len(node.value.elts) - if len(targets) != rhs_count or rhs_count == 1: - return - rhs_names = node.value.elts - - for target, lhs_name in zip(targets, rhs_names): - if not isinstance(lhs_name, astroid.Name): - continue - if not isinstance(target, astroid.AssignName): - continue - if isinstance(scope, astroid.ClassDef) and target.name in scope_locals: - # Check that the scope is different than a class level, which is usually - # a pattern to expose module level attributes as class level ones. - continue - if target.name == lhs_name.name: - self.add_message( - "self-assigning-variable", args=(target.name,), node=target - ) - - def _check_redeclared_assign_name(self, targets): - dummy_variables_rgx = lint_utils.get_global_option( - self, "dummy-variables-rgx", default=None - ) - - for target in targets: - if not isinstance(target, astroid.Tuple): - continue - - found_names = [] - for element in target.elts: - if isinstance(element, astroid.Tuple): - self._check_redeclared_assign_name([element]) - elif isinstance(element, astroid.AssignName) and element.name != "_": - if dummy_variables_rgx and dummy_variables_rgx.match(element.name): - return - found_names.append(element.name) - - names = collections.Counter(found_names) - for name, count in names.most_common(): - if count > 1: - self.add_message( - "redeclared-assigned-name", args=(name,), node=target - ) - - @utils.check_messages("self-assigning-variable", "redeclared-assigned-name") - def visit_assign(self, node): - self._check_self_assigning_variable(node) - self._check_redeclared_assign_name(node.targets) - - @utils.check_messages("redeclared-assigned-name") - def visit_for(self, node): - self._check_redeclared_assign_name([node.target]) - - -KNOWN_NAME_TYPES = { - "module", - "const", - "class", - "function", - "method", - "attr", - "argument", - "variable", - "class_attribute", - "inlinevar", -} - - -HUMAN_READABLE_TYPES = { - "module": "module", - "const": "constant", - "class": "class", - "function": "function", - "method": "method", - "attr": "attribute", - "argument": "argument", - "variable": "variable", - "class_attribute": "class attribute", - "inlinevar": "inline iteration", -} - -DEFAULT_NAMING_STYLES = { - "module": "snake_case", - "const": "UPPER_CASE", - "class": "PascalCase", - "function": "snake_case", - "method": "snake_case", - "attr": "snake_case", - "argument": "snake_case", - "variable": "snake_case", - "class_attribute": "any", - "inlinevar": "any", -} - - -def _create_naming_options(): - name_options = [] - for name_type in sorted(KNOWN_NAME_TYPES): - human_readable_name = HUMAN_READABLE_TYPES[name_type] - default_style = DEFAULT_NAMING_STYLES[name_type] - name_type = name_type.replace("_", "-") - name_options.append( - ( - "%s-naming-style" % (name_type,), - { - "default": default_style, - "type": "choice", - "choices": list(NAMING_STYLES.keys()), - "metavar": " - - - - - - - - -

    - - - -""" diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__init__.py b/env/lib/python3.8/site-packages/starlette/middleware/__init__.py deleted file mode 100644 index 5ac5b96c..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import typing - - -class Middleware: - def __init__(self, cls: type, **options: typing.Any) -> None: - self.cls = cls - self.options = options - - def __iter__(self) -> typing.Iterator: - as_tuple = (self.cls, self.options) - return iter(as_tuple) - - def __repr__(self) -> str: - class_name = self.__class__.__name__ - option_strings = [f"{key}={value!r}" for key, value in self.options.items()] - args_repr = ", ".join([self.cls.__name__] + option_strings) - return f"{class_name}({args_repr})" diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index b72405e312261f641b7e866d69209877be2c91b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1221 zcmZux&2G~`5Z)ihaY74~sEWh^AueEv#z9vWDm#*o$-<$5b2a0bmPbY z-nsp232>0uiggh42-FZB{kHNIYMw#Oa1CaEz>fG&wvE^6oW7~*g2A)S3(L3E)HZg) zWOAeCb~lMl5oP1NcMo63I$Zd6pI(~?Py+hW=_XkeCZ-3Q^IN;@`Qtf#HmAPt+LjPe z5*i}}4mu6TN{EVqwgH_T8|#d+IIRZbJM}c$^#zO_+^tD3Orhg+Xa=oN4-L{$-!iHi z(jtOJDii9_W%&N1QXS>r(JK&Q+d_;pIY|JPT@Ye>5+*fB>lD*mSr;^9w)|~6)%Xjs z-ba{sSY%pbCd&bu#-GL&K$u-4Wi&Dq8)%S#0LNK!sxx37POaMCcF}s>8deXvZtxk8 F{{xW}7=Hi& diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/authentication.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/authentication.cpython-38.pyc deleted file mode 100644 index 2f39b7c7625f9339cba2eedcc3b923f52e0fb751..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1939 zcmaJ>OK%)S5bo~jdF<}&!%sE{q(tPh2isC45J(ZiSdkMXtSGjX&_WuGr`z$`GqaPP zS?sLF99WAR5c{G1plJ1T*8$bxrC}&Kh_8{QrC1(0ZWF+;$pX?N)L-SGq?{>*3bcF*EZx4*Thr zIx3#1JR79BGTy}uf^b(i*B`BBnQ@<}NcF!_#@>tunKFD6d`B4T^aoX(R7}7`5kVyp zOg5CIxU%;hsf!Tm z^gOJ-SzjrVY$fYwOT#q7Smn~;o>KABC;Rt;k3Rk|Sjme}$EqmQN^+Us$`q~u;d1uU zctOxl`$Z67EV&1Qcn)<~=k4guO=ViXI0Hf2c?GGf&mo4OQ>ka*nroH9i?LyThmpSq zQBp|(NOs`ryCr#rm1CuKW<7#tcu0`;o1~y69n)hzTEzOjvPynNC+o-dQQHg&4Ij_2noYbg@*ZUm`^-l^IWB*XF;ZCe{g<=I6 zHi%wC(LjN{qJ0z}fG|Gh){hcZ>N5DOoykU$1 zN}Sf;GK>A~x8@fZt#$r2qf` diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/base.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/base.cpython-38.pyc deleted file mode 100644 index 893976be6be3ee415215f4fae4bd17d31bddc618..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2686 zcma)8OLJQ_6qa-!zJA6{(vq~L!=q&|Ozn0UW?H7xX=qE^1sRA-VZ6C>V=0M~`*0*V zB^ifBlbJXRRxH?L5ik26SkZr>Ei2fvV?jCRUONv64D#q)=}0=#`OeEp9 z`@eaF{DPB{&4$T6=xP@TC!B_)m3?W8!kmRHvRW2Jo)y}W({duW<)(8x%tcW**eq#PGOnmBvs3(uM}#}v-6h=JVXZ2sO;XGK3NIn^ zHEMDTV!bDnt}){+2-QtuCCs^|mLiBc@$#5evrTTU`RK`9w~I&GqO&24(`+YQVeF=e zc^d_uYz|EBL08X!2!e{X7_SIR*qm~9U~!AvyP&FYMNW9Ya}I3o^4zZ7%8P<1a_@lg zJTJh!1oJX*ig2pL%fP9mYD}2PPXi?$KYjYe=N-;N@jQ@XzGfLKfOmSlqq>1^uNYSf z-IHG|HA`OY zlS2fM^{t`x1pN3hLGNu6O_9s3@7cBudsrXnsx@TUo^7Y^WT$pcovPXM#@3tYTPs?3 zYgA6deKk9S7p*2MKuo?JgrOgcZ*|R;sI#0xf}7=e+yFYI-fcWN^6k_r899eL0J2nw zk0%u>O=yWuQ=1|E7wEDRH6~|adxjJ~YTR-#K(uzCtDk^qa!7|{o57b2$vz;pYV9+i z_C6huRcGIZ$fpN%kL=MswrB0xOAZIrc1znx&r(2v!w6r5MBT~ zxiBxn-1R5=F64?5q=`&N(BxFh!|Vs>>IRUlnSpgk2W&tG_OTCqO+F^@YVd_29s9*M zsb|PC9D=N4b$dFqE5=LBF%DR)Co&_Z=1dKX<~(6GyPe47D)1BnO(>%?Z0mzF{QSs6 z>UY8fChBe-k8YixPu?2)1Pm}e2ws;LK-kt4I$eFdTE~#nZMF;rNz6?d3bjav^0v%|dA4 zf=412GSC2xv$&~+l4vngl)-a<{FYpnG%$*djZctR2qgNId=JS*B&lDzDVAq?BOaM=hxsZTecF`?S#20^6b|ufKOYGOKRiIm!{|jp>z1@yN5EPqNzR@)#T5hYNGSXNxT~~ro>2= z@c)U(OGxl?i7KYBnm0y&R2D{w{9(+yNhj9nYqQ7yO$|&>SSAz_k51du`RX-B7-fG- zT&tavAHql80AePO3M&MDS~FDo0yA}TA^U%%vS+3KG;zF)1xuxBW~!u0p+3gD4|OV7 v428+hJr6n>hw>A=`!*7M%vl;3?@os0U9_@7q|l{G5TY~e0<~%Nwe9=`qZ)vD diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/cors.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/cors.cpython-38.pyc deleted file mode 100644 index 448a1fcbe1d8aabc96700f2ed393f40f786214e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4573 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 Us6zQg%X!P0cIKRMr{K8%3o-b*NB{r; diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/gzip.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/gzip.cpython-38.pyc deleted file mode 100644 index 5b718bb29174e01e61cbae92dea01628fa2b1435..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3000 zcmai0OK%)S5T2gL&g^)-Yn+e=L||Tr1!6;h2&5#+LwO-$q!=!98OGZkd+eFnrKdNR zS8FLE5jUj#fE?Dx{0R>5Cs1EG=w$}NEzUA4s{UETz}uOfJCT#Sk;_Q#WL{p2YPlczc@PD8J*wwn z6f*0&#a-?_u()^Mj^@DCxDU<;*APBuJa}aDIu9SX(L85sR(tLVPPA6rw)Ss`gbP{f z=B>U;)-!Ryw>|A&TDyMpQm?1|TcRwJ4Wa$pq9f9~LVIhSZck`;O%%LCTTM3)%tiF_ za}Z(CRU#ZO9N}`CJC7WrtQUErCVUYgM$*?cGW_&%{n5#gl&+ z)P3w|CxJeVJT20^pT}i75V|IX>dT@-)*Lq)+vr!&%LR}j8(Oh7v_YZHn)R6B^0I+1 zavlUbyQRqPOi3)ch!0QCuc*AY(o1`%`$aG5YzuyRXH$sm^jBMF;h3&cA9l9gNJzm?lw`=$U3v4;)?tOdD8+x#d zJ#_9nHxXYqEQ+!GOEkNHRKNC6M2ND zz_Ohr%i@^)SCV}!)?gu9U`@8j+!xunnh(7RmIyLzQ6#yDV;#nE-sSy_#*H}sv7cns z7fCkPPFg5=6eH;qA=}G<$U8(PikT5i4GF;omt7`Fiw zKn0)}0|kBrPzc)qiU?yTW-Il6AX(UFqC zJ>>yoeDV|>br2ObAg=m_Y;bHQ5D$STU&s6zfRVKh0k#BY2-qNnSR-b@VQty7@Q_IH zR@*TFY>c3rbm@2}Rhuy>+;(3S>(44rAw_+XES^)jisQ#f-UlYE(gUGw+$cop1|~iH zi{x3Qhdp~}n-uXz<^PAQ_yZDW+kVL8J$RWtWaT|14W!8-8`)Lj*h4zN7#Vus-gA|M zgn=m8a+$(>*3cWx^QPGax^WMZSL-l%+3r)jVfXWuW)m%q zZsSv+X_L1O^skRvmHw~1zdW?^UoW%kjBUtTzdmoFS86e3bA!``Re2I&FgQXPd$~%c zrC2tI8!XNW*Smc8JMGfn-xNo>o_D2)iN7Y7AZRn~$YjT$ajl6gBaRd`x-vTiBlGKm6|j=M?L7t%4S zN+qLK!g+i*k-KqKBdBnTZ5=4tFFJ`5c8Hk`^cwg|Iyg0( zd7jA)4f!rkmG2RGp9rB>l0GjlJd~b{+EZ7Vlpv}ER8dRH1p!;EqX>~qo&o8QU&f8b zlsrtbpf{1iTl7Br$-I=>_UhmmDZ7;HB&m5KE)`w1R0@T7Xx#1>D$T`JDZ3Jtm8?Fc zjWKK+vLDb(lc1O+zTGrYBtOPDI&t`fTIPvL;N^Y?PdZVW2ZZr`)SAp8UzU}9j0H?N oHig;LWGcPYMd_d^We!cFgL752zd$!H>BjIjyn4!MwwgEp2e;apegFUf diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/httpsredirect.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/httpsredirect.cpython-38.pyc deleted file mode 100644 index e36028c952c752f38a2950c3962136435098c77f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmaJ=%}(4f5VjNNXO{)G0=01CngeXrs#Pmh6;P>w)UMDjTyn9}*cA&&HnqL1K-m+h zH~It|+GC%gxArY^?TJ_DsWS-+duc8C%Xr3~eEw#9I6vPcFwQ^!TLi)1WiavLrT%M5-YVsyRz+srB3LiZs?|7=%s$>Q?f$@6V4?O&V>~=gxe>9cLRAy zKui0u_YOYoo)iNmW7Cs5A7)wxtn{|}J9}GsUV1$l%fYEEoqjybWy$(76EP;39S$ru zVd}>Kl7v){(2};G!n(GEE!ZUsnRKKpJ@7f#Ot``WpD!p7^2iI?%@X2Bt;{3tA8ksz6HG4XA2>4-zmflaJNnJ5eq0{dwCl zY2L{P`T8i!qxeLM_3@FE$@i9^e5K>D(ytKv| zDzb>CQ|VaRW32=0W*=OG9~3L4mND#R(j>!p@DzQtoP$!Bk>>GG$iP=9a=nk`LuE?; zXsAsVrBbcpVNf(rqF5??G<5^`Y7TAuwQ3_g04VK|O2WlyF?mh4&f%-ucThD;4fA*g z${j~Z!Z{X7V=h8hXp^?-L%Kj)blLh}@#~{O1JfX3&dVm}=}?Rkv|F5i8bwJRQP>4) z0l`JUCQ#U9Y7GIKcm|N1!d}6>8jt$4ZC9Rd&zY-?rD9bP!vD^2si@Uzy{hl_8tO|7>L?BT$;}?)wcTHDKb$5OBYCq`j_X#}f-~AH) z-bcu9$Q*u5U_ON*zXiewqX`MhHw`H8Mq;F9V5U}J(Nb;)HptDyN!`Fry}&EvR#Hj* zz)$;vzJj-tYT6(47jq{WNC$(#v=-FTp*Z{H%17&Js1^cGv|d{;I#vv_wg$4 z2U+EX#eCNH*a`-i4fy-@Pz#Iz!=_`#621}vKv$NcSEM&gw3$S!Q!@=$n-SRT%K})q z%-8h5u3p&gbe3aSmqx20;;G0e<)Mrf*Z!hXT^V+=WKBEZk)FufF4({K;M{_72Zp>2 zB&RtEiK5$vGIL{-?jUdFCQv)KfI5uk_6Y(rH+RI%9F{M+%(y}fkT3$E%$fBgcq|?| zQAbCK3}Tq2iqb9ymuK5Su4yj}<1AKTH~(!drKOYwq=oHuGq~vFg|1AB<#}0KD%wu~hsx0cLhNBoFy{K@c?E_)ZyhHaP$AoW%+1XmgOcq07Lm^n zt@CglE49u4YHvYBZPLTRYxpzbELdC?Pg8IS6(o5R6H*n>#Ru>ieDN-7ojE5b&&i2; zH&Tm}V-xl1Xm#|~0-rp`ChF(py5Hhz^iI(j)+@WJAik9KlH_0!FFL54oL%glua94- ze;#G^3)ilU*T=`N7k~A;)3Xzes=$jwTT8N&X`A)ZF0|OPMT@tJFIc6*foV~E+9_Lk z8MV`>;XwC-L~mH)!(su8RHWU--F{syC*h+g>G79VFoG2pM@hKX;#MLV^0ceg3h?3# zp7cHvtZMNNZdt`b3ReUkBrbwPehh@rD)o$$Kz(XJb$T$YzZ_?PT1F`W>EDiBrR(Ew zs@ryyBw^URk#t}tZ#EAf(ikY4jt9q-xZSc9OMyoht_hr8RyYTHm-q;Xwv$f8q%cr` z`6@7B1zy|@w?u{k7VjZJjM{JS-(RAMQbboGzkss>KD4FMR^((I2tq#!FaferrNaP! z7=9j%n&BCzM&8`0%1t0nSZtz(WC+MqV-P!EhBr&7{V+^Bte4=t8io&hQBr;p*t4_) z^&Dpl+J2D1)h15iCfLxl8D~mcbDd5i>L{!tfqztp=tpuHNfFTlf^Y5&U5fE-ooB4}!si57^aY;gKS`CC~zLffhl%39a^Sl+L}0 TolRm0JO~>E4Mq(BpEmyiq9bzw diff --git a/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/trustedhost.cpython-38.pyc b/env/lib/python3.8/site-packages/starlette/middleware/__pycache__/trustedhost.cpython-38.pyc deleted file mode 100644 index d847aef5b267d3154d8984b65ba19d48db48e5ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1989 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 YOGK{|l_cc;Sm4#CN|ATi=xBvhE diff --git a/env/lib/python3.8/site-packages/starlette/middleware/authentication.py b/env/lib/python3.8/site-packages/starlette/middleware/authentication.py deleted file mode 100644 index c9e4d4f6..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/authentication.py +++ /dev/null @@ -1,52 +0,0 @@ -import typing - -from starlette.authentication import ( - AuthCredentials, - AuthenticationBackend, - AuthenticationError, - UnauthenticatedUser, -) -from starlette.requests import HTTPConnection -from starlette.responses import PlainTextResponse, Response -from starlette.types import ASGIApp, Receive, Scope, Send - - -class AuthenticationMiddleware: - def __init__( - self, - app: ASGIApp, - backend: AuthenticationBackend, - on_error: typing.Callable[ - [HTTPConnection, AuthenticationError], Response - ] = None, - ) -> None: - self.app = app - self.backend = backend - self.on_error = ( - on_error if on_error is not None else self.default_on_error - ) # type: typing.Callable[[HTTPConnection, AuthenticationError], Response] - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] not in ["http", "websocket"]: - await self.app(scope, receive, send) - return - - conn = HTTPConnection(scope) - try: - auth_result = await self.backend.authenticate(conn) - except AuthenticationError as exc: - response = self.on_error(conn, exc) - if scope["type"] == "websocket": - await send({"type": "websocket.close", "code": 1000}) - else: - await response(scope, receive, send) - return - - if auth_result is None: - auth_result = AuthCredentials(), UnauthenticatedUser() - scope["auth"], scope["user"] = auth_result - await self.app(scope, receive, send) - - @staticmethod - def default_on_error(conn: HTTPConnection, exc: Exception) -> Response: - return PlainTextResponse(str(exc), status_code=400) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/base.py b/env/lib/python3.8/site-packages/starlette/middleware/base.py deleted file mode 100644 index 6c6a43b1..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/base.py +++ /dev/null @@ -1,67 +0,0 @@ -import asyncio -import typing - -from starlette.requests import Request -from starlette.responses import Response, StreamingResponse -from starlette.types import ASGIApp, Receive, Scope, Send - -RequestResponseEndpoint = typing.Callable[[Request], typing.Awaitable[Response]] -DispatchFunction = typing.Callable[ - [Request, RequestResponseEndpoint], typing.Awaitable[Response] -] - - -class BaseHTTPMiddleware: - def __init__(self, app: ASGIApp, dispatch: DispatchFunction = None) -> None: - self.app = app - self.dispatch_func = self.dispatch if dispatch is None else dispatch - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] != "http": - await self.app(scope, receive, send) - return - - request = Request(scope, receive=receive) - response = await self.dispatch_func(request, self.call_next) - await response(scope, receive, send) - - async def call_next(self, request: Request) -> Response: - loop = asyncio.get_event_loop() - queue = asyncio.Queue() # type: asyncio.Queue - - scope = request.scope - receive = request.receive - send = queue.put - - async def coro() -> None: - try: - await self.app(scope, receive, send) - finally: - await queue.put(None) - - task = loop.create_task(coro()) - message = await queue.get() - if message is None: - task.result() - raise RuntimeError("No response returned.") - assert message["type"] == "http.response.start" - - async def body_stream() -> typing.AsyncGenerator[bytes, None]: - while True: - message = await queue.get() - if message is None: - break - assert message["type"] == "http.response.body" - yield message.get("body", b"") - task.result() - - response = StreamingResponse( - status_code=message["status"], content=body_stream() - ) - response.raw_headers = message["headers"] - return response - - async def dispatch( - self, request: Request, call_next: RequestResponseEndpoint - ) -> Response: - raise NotImplementedError() # pragma: no cover diff --git a/env/lib/python3.8/site-packages/starlette/middleware/cors.py b/env/lib/python3.8/site-packages/starlette/middleware/cors.py deleted file mode 100644 index 338aee86..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/cors.py +++ /dev/null @@ -1,167 +0,0 @@ -import functools -import re -import typing - -from starlette.datastructures import Headers, MutableHeaders -from starlette.responses import PlainTextResponse, Response -from starlette.types import ASGIApp, Message, Receive, Scope, Send - -ALL_METHODS = ("DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT") -SAFELISTED_HEADERS = {"Accept", "Accept-Language", "Content-Language", "Content-Type"} - - -class CORSMiddleware: - def __init__( - self, - app: ASGIApp, - allow_origins: typing.Sequence[str] = (), - allow_methods: typing.Sequence[str] = ("GET",), - allow_headers: typing.Sequence[str] = (), - allow_credentials: bool = False, - allow_origin_regex: str = None, - expose_headers: typing.Sequence[str] = (), - max_age: int = 600, - ) -> None: - - if "*" in allow_methods: - allow_methods = ALL_METHODS - - compiled_allow_origin_regex = None - if allow_origin_regex is not None: - compiled_allow_origin_regex = re.compile(allow_origin_regex) - - simple_headers = {} - if "*" in allow_origins: - simple_headers["Access-Control-Allow-Origin"] = "*" - if allow_credentials: - simple_headers["Access-Control-Allow-Credentials"] = "true" - if expose_headers: - simple_headers["Access-Control-Expose-Headers"] = ", ".join(expose_headers) - - preflight_headers = {} - if "*" in allow_origins: - preflight_headers["Access-Control-Allow-Origin"] = "*" - else: - preflight_headers["Vary"] = "Origin" - preflight_headers.update( - { - "Access-Control-Allow-Methods": ", ".join(allow_methods), - "Access-Control-Max-Age": str(max_age), - } - ) - allow_headers = sorted(SAFELISTED_HEADERS | set(allow_headers)) - if allow_headers and "*" not in allow_headers: - preflight_headers["Access-Control-Allow-Headers"] = ", ".join(allow_headers) - if allow_credentials: - preflight_headers["Access-Control-Allow-Credentials"] = "true" - - self.app = app - self.allow_origins = allow_origins - self.allow_methods = allow_methods - self.allow_headers = [h.lower() for h in allow_headers] - self.allow_all_origins = "*" in allow_origins - self.allow_all_headers = "*" in allow_headers - self.allow_origin_regex = compiled_allow_origin_regex - self.simple_headers = simple_headers - self.preflight_headers = preflight_headers - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] != "http": # pragma: no cover - await self.app(scope, receive, send) - return - - method = scope["method"] - headers = Headers(scope=scope) - origin = headers.get("origin") - - if origin is None: - await self.app(scope, receive, send) - return - - if method == "OPTIONS" and "access-control-request-method" in headers: - response = self.preflight_response(request_headers=headers) - await response(scope, receive, send) - return - - await self.simple_response(scope, receive, send, request_headers=headers) - - def is_allowed_origin(self, origin: str) -> bool: - if self.allow_all_origins: - return True - - if self.allow_origin_regex is not None and self.allow_origin_regex.fullmatch( - origin - ): - return True - - return origin in self.allow_origins - - def preflight_response(self, request_headers: Headers) -> Response: - requested_origin = request_headers["origin"] - requested_method = request_headers["access-control-request-method"] - requested_headers = request_headers.get("access-control-request-headers") - - headers = dict(self.preflight_headers) - failures = [] - - if self.is_allowed_origin(origin=requested_origin): - if not self.allow_all_origins: - # If self.allow_all_origins is True, then the "Access-Control-Allow-Origin" - # header is already set to "*". - # If we only allow specific origins, then we have to mirror back - # the Origin header in the response. - headers["Access-Control-Allow-Origin"] = requested_origin - else: - failures.append("origin") - - if requested_method not in self.allow_methods: - failures.append("method") - - # If we allow all headers, then we have to mirror back any requested - # headers in the response. - if self.allow_all_headers and requested_headers is not None: - headers["Access-Control-Allow-Headers"] = requested_headers - elif requested_headers is not None: - for header in [h.lower() for h in requested_headers.split(",")]: - if header.strip() not in self.allow_headers: - failures.append("headers") - - # We don't strictly need to use 400 responses here, since its up to - # the browser to enforce the CORS policy, but its more informative - # if we do. - if failures: - failure_text = "Disallowed CORS " + ", ".join(failures) - return PlainTextResponse(failure_text, status_code=400, headers=headers) - - return PlainTextResponse("OK", status_code=200, headers=headers) - - async def simple_response( - self, scope: Scope, receive: Receive, send: Send, request_headers: Headers - ) -> None: - send = functools.partial(self.send, send=send, request_headers=request_headers) - await self.app(scope, receive, send) - - async def send( - self, message: Message, send: Send, request_headers: Headers - ) -> None: - if message["type"] != "http.response.start": - await send(message) - return - - message.setdefault("headers", []) - headers = MutableHeaders(scope=message) - headers.update(self.simple_headers) - origin = request_headers["Origin"] - has_cookie = "cookie" in request_headers - - # If request includes any cookie headers, then we must respond - # with the specific origin instead of '*'. - if self.allow_all_origins and has_cookie: - headers["Access-Control-Allow-Origin"] = origin - - # If we only allow specific origins, then we have to mirror back - # the Origin header in the response. - elif not self.allow_all_origins and self.is_allowed_origin(origin=origin): - headers["Access-Control-Allow-Origin"] = origin - headers.add_vary_header("Origin") - await send(message) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/errors.py b/env/lib/python3.8/site-packages/starlette/middleware/errors.py deleted file mode 100644 index f1f8bd3d..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/errors.py +++ /dev/null @@ -1,246 +0,0 @@ -import asyncio -import html -import inspect -import traceback -import typing - -from starlette.concurrency import run_in_threadpool -from starlette.requests import Request -from starlette.responses import HTMLResponse, PlainTextResponse, Response -from starlette.types import ASGIApp, Message, Receive, Scope, Send - -STYLES = """ -p { - color: #211c1c; -} -.traceback-container { - border: 1px solid #038BB8; -} -.traceback-title { - background-color: #038BB8; - color: lemonchiffon; - padding: 12px; - font-size: 20px; - margin-top: 0px; -} -.frame-line { - padding-left: 10px; - font-family: monospace; -} -.frame-filename { - font-family: monospace; -} -.center-line { - background-color: #038BB8; - color: #f9f6e1; - padding: 5px 0px 5px 5px; -} -.lineno { - margin-right: 5px; -} -.frame-title { - font-weight: unset; - padding: 10px 10px 10px 10px; - background-color: #E4F4FD; - margin-right: 10px; - color: #191f21; - font-size: 17px; - border: 1px solid #c7dce8; -} -.collapse-btn { - float: right; - padding: 0px 5px 1px 5px; - border: solid 1px #96aebb; - cursor: pointer; -} -.collapsed { - display: none; -} -.source-code { - font-family: courier; - font-size: small; - padding-bottom: 10px; -} -""" - -JS = """ - -""" - -TEMPLATE = """ - - - - Starlette Debugger - - -

    500 Server Error

    -

    {error}

    -
    -

    Traceback

    -
    {exc_html}
    -
    - {js} - - -""" - -FRAME_TEMPLATE = """ -
    -

    File {frame_filename}, - line {frame_lineno}, - in {frame_name} - {collapse_button} -

    -
    {code_context}
    -
    -""" - -LINE = """ -

    -{lineno}. {line}

    -""" - -CENTER_LINE = """ -

    -{lineno}. {line}

    -""" - - -class ServerErrorMiddleware: - """ - Handles returning 500 responses when a server error occurs. - - If 'debug' is set, then traceback responses will be returned, - otherwise the designated 'handler' will be called. - - This middleware class should generally be used to wrap *everything* - else up, so that unhandled exceptions anywhere in the stack - always result in an appropriate 500 response. - """ - - def __init__( - self, app: ASGIApp, handler: typing.Callable = None, debug: bool = False - ) -> None: - self.app = app - self.handler = handler - self.debug = debug - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] != "http": - await self.app(scope, receive, send) - return - - response_started = False - - async def _send(message: Message) -> None: - nonlocal response_started, send - - if message["type"] == "http.response.start": - response_started = True - await send(message) - - try: - await self.app(scope, receive, _send) - except Exception as exc: - if not response_started: - request = Request(scope) - if self.debug: - # In debug mode, return traceback responses. - response = self.debug_response(request, exc) - elif self.handler is None: - # Use our default 500 error handler. - response = self.error_response(request, exc) - else: - # Use an installed 500 error handler. - if asyncio.iscoroutinefunction(self.handler): - response = await self.handler(request, exc) - else: - response = await run_in_threadpool(self.handler, request, exc) - - await response(scope, receive, send) - - # We always continue to raise the exception. - # This allows servers to log the error, or allows test clients - # to optionally raise the error within the test case. - raise exc from None - - def format_line( - self, index: int, line: str, frame_lineno: int, frame_index: int - ) -> str: - values = { - # HTML escape - line could contain < or > - "line": html.escape(line).replace(" ", " "), - "lineno": (frame_lineno - frame_index) + index, - } - - if index != frame_index: - return LINE.format(**values) - return CENTER_LINE.format(**values) - - def generate_frame_html(self, frame: inspect.FrameInfo, is_collapsed: bool) -> str: - code_context = "".join( - self.format_line(index, line, frame.lineno, frame.index) # type: ignore - for index, line in enumerate(frame.code_context or []) - ) - - values = { - # HTML escape - filename could contain < or >, especially if it's a virtual file e.g. in the REPL - "frame_filename": html.escape(frame.filename), - "frame_lineno": frame.lineno, - # HTML escape - if you try very hard it's possible to name a function with < or > - "frame_name": html.escape(frame.function), - "code_context": code_context, - "collapsed": "collapsed" if is_collapsed else "", - "collapse_button": "+" if is_collapsed else "‒", - } - return FRAME_TEMPLATE.format(**values) - - def generate_html(self, exc: Exception, limit: int = 7) -> str: - traceback_obj = traceback.TracebackException.from_exception( - exc, capture_locals=True - ) - frames = inspect.getinnerframes( - traceback_obj.exc_traceback, limit # type: ignore - ) - - exc_html = "" - is_collapsed = False - for frame in reversed(frames): - exc_html += self.generate_frame_html(frame, is_collapsed) - is_collapsed = True - - # escape error class and text - error = f"{html.escape(traceback_obj.exc_type.__name__)}: {html.escape(str(traceback_obj))}" - - return TEMPLATE.format(styles=STYLES, js=JS, error=error, exc_html=exc_html) - - def generate_plain_text(self, exc: Exception) -> str: - return "".join(traceback.format_tb(exc.__traceback__)) - - def debug_response(self, request: Request, exc: Exception) -> Response: - accept = request.headers.get("accept", "") - - if "text/html" in accept: - content = self.generate_html(exc) - return HTMLResponse(content, status_code=500) - content = self.generate_plain_text(exc) - return PlainTextResponse(content, status_code=500) - - def error_response(self, request: Request, exc: Exception) -> Response: - return PlainTextResponse("Internal Server Error", status_code=500) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/gzip.py b/env/lib/python3.8/site-packages/starlette/middleware/gzip.py deleted file mode 100644 index bb634e36..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/gzip.py +++ /dev/null @@ -1,97 +0,0 @@ -import gzip -import io - -from starlette.datastructures import Headers, MutableHeaders -from starlette.types import ASGIApp, Message, Receive, Scope, Send - - -class GZipMiddleware: - def __init__(self, app: ASGIApp, minimum_size: int = 500) -> None: - self.app = app - self.minimum_size = minimum_size - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] == "http": - headers = Headers(scope=scope) - if "gzip" in headers.get("Accept-Encoding", ""): - responder = GZipResponder(self.app, self.minimum_size) - await responder(scope, receive, send) - return - await self.app(scope, receive, send) - - -class GZipResponder: - def __init__(self, app: ASGIApp, minimum_size: int) -> None: - self.app = app - self.minimum_size = minimum_size - self.send = unattached_send # type: Send - self.initial_message = {} # type: Message - self.started = False - self.gzip_buffer = io.BytesIO() - self.gzip_file = gzip.GzipFile(mode="wb", fileobj=self.gzip_buffer) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - self.send = send - await self.app(scope, receive, self.send_with_gzip) - - async def send_with_gzip(self, message: Message) -> None: - message_type = message["type"] - if message_type == "http.response.start": - # Don't send the initial message until we've determined how to - # modify the ougoging headers correctly. - self.initial_message = message - elif message_type == "http.response.body" and not self.started: - self.started = True - body = message.get("body", b"") - more_body = message.get("more_body", False) - if len(body) < self.minimum_size and not more_body: - # Don't apply GZip to small outgoing responses. - await self.send(self.initial_message) - await self.send(message) - elif not more_body: - # Standard GZip response. - self.gzip_file.write(body) - self.gzip_file.close() - body = self.gzip_buffer.getvalue() - - headers = MutableHeaders(raw=self.initial_message["headers"]) - headers["Content-Encoding"] = "gzip" - headers["Content-Length"] = str(len(body)) - headers.add_vary_header("Accept-Encoding") - message["body"] = body - - await self.send(self.initial_message) - await self.send(message) - else: - # Initial body in streaming GZip response. - headers = MutableHeaders(raw=self.initial_message["headers"]) - headers["Content-Encoding"] = "gzip" - headers.add_vary_header("Accept-Encoding") - del headers["Content-Length"] - - self.gzip_file.write(body) - message["body"] = self.gzip_buffer.getvalue() - self.gzip_buffer.seek(0) - self.gzip_buffer.truncate() - - await self.send(self.initial_message) - await self.send(message) - - elif message_type == "http.response.body": - # Remaining body in streaming GZip response. - body = message.get("body", b"") - more_body = message.get("more_body", False) - - self.gzip_file.write(body) - if not more_body: - self.gzip_file.close() - - message["body"] = self.gzip_buffer.getvalue() - self.gzip_buffer.seek(0) - self.gzip_buffer.truncate() - - await self.send(message) - - -async def unattached_send(message: Message) -> None: - raise RuntimeError("send awaitable not set") # pragma: no cover diff --git a/env/lib/python3.8/site-packages/starlette/middleware/httpsredirect.py b/env/lib/python3.8/site-packages/starlette/middleware/httpsredirect.py deleted file mode 100644 index a8359067..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/httpsredirect.py +++ /dev/null @@ -1,19 +0,0 @@ -from starlette.datastructures import URL -from starlette.responses import RedirectResponse -from starlette.types import ASGIApp, Receive, Scope, Send - - -class HTTPSRedirectMiddleware: - def __init__(self, app: ASGIApp) -> None: - self.app = app - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] in ("http", "websocket") and scope["scheme"] in ("http", "ws"): - url = URL(scope=scope) - redirect_scheme = {"http": "https", "ws": "wss"}[url.scheme] - netloc = url.hostname if url.port in (80, 443) else url.netloc - url = url.replace(scheme=redirect_scheme, netloc=netloc) - response = RedirectResponse(url, status_code=307) - await response(scope, receive, send) - else: - await self.app(scope, receive, send) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/sessions.py b/env/lib/python3.8/site-packages/starlette/middleware/sessions.py deleted file mode 100644 index aad61ff2..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/sessions.py +++ /dev/null @@ -1,75 +0,0 @@ -import json -import typing -from base64 import b64decode, b64encode - -import itsdangerous -from itsdangerous.exc import BadTimeSignature, SignatureExpired - -from starlette.datastructures import MutableHeaders, Secret -from starlette.requests import HTTPConnection -from starlette.types import ASGIApp, Message, Receive, Scope, Send - - -class SessionMiddleware: - def __init__( - self, - app: ASGIApp, - secret_key: typing.Union[str, Secret], - session_cookie: str = "session", - max_age: int = 14 * 24 * 60 * 60, # 14 days, in seconds - same_site: str = "lax", - https_only: bool = False, - ) -> None: - self.app = app - self.signer = itsdangerous.TimestampSigner(str(secret_key)) - self.session_cookie = session_cookie - self.max_age = max_age - self.security_flags = "httponly; samesite=" + same_site - if https_only: # Secure flag can be used with HTTPS only - self.security_flags += "; secure" - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] not in ("http", "websocket"): # pragma: no cover - await self.app(scope, receive, send) - return - - connection = HTTPConnection(scope) - initial_session_was_empty = True - - if self.session_cookie in connection.cookies: - data = connection.cookies[self.session_cookie].encode("utf-8") - try: - data = self.signer.unsign(data, max_age=self.max_age) - scope["session"] = json.loads(b64decode(data)) - initial_session_was_empty = False - except (BadTimeSignature, SignatureExpired): - scope["session"] = {} - else: - scope["session"] = {} - - async def send_wrapper(message: Message) -> None: - if message["type"] == "http.response.start": - if scope["session"]: - # We have session data to persist. - data = b64encode(json.dumps(scope["session"]).encode("utf-8")) - data = self.signer.sign(data) - headers = MutableHeaders(scope=message) - header_value = "%s=%s; path=/; Max-Age=%d; %s" % ( - self.session_cookie, - data.decode("utf-8"), - self.max_age, - self.security_flags, - ) - headers.append("Set-Cookie", header_value) - elif not initial_session_was_empty: - # The session has been cleared. - headers = MutableHeaders(scope=message) - header_value = "%s=%s; %s" % ( - self.session_cookie, - "null; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT;", - self.security_flags, - ) - headers.append("Set-Cookie", header_value) - await send(message) - - await self.app(scope, receive, send_wrapper) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/trustedhost.py b/env/lib/python3.8/site-packages/starlette/middleware/trustedhost.py deleted file mode 100644 index 39836524..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/trustedhost.py +++ /dev/null @@ -1,59 +0,0 @@ -import typing - -from starlette.datastructures import URL, Headers -from starlette.responses import PlainTextResponse, RedirectResponse, Response -from starlette.types import ASGIApp, Receive, Scope, Send - -ENFORCE_DOMAIN_WILDCARD = "Domain wildcard patterns must be like '*.example.com'." - - -class TrustedHostMiddleware: - def __init__( - self, - app: ASGIApp, - allowed_hosts: typing.Sequence[str] = None, - www_redirect: bool = True, - ) -> None: - if allowed_hosts is None: - allowed_hosts = ["*"] - - for pattern in allowed_hosts: - assert "*" not in pattern[1:], ENFORCE_DOMAIN_WILDCARD - if pattern.startswith("*") and pattern != "*": - assert pattern.startswith("*."), ENFORCE_DOMAIN_WILDCARD - self.app = app - self.allowed_hosts = list(allowed_hosts) - self.allow_any = "*" in allowed_hosts - self.www_redirect = www_redirect - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if self.allow_any or scope["type"] not in ( - "http", - "websocket", - ): # pragma: no cover - await self.app(scope, receive, send) - return - - headers = Headers(scope=scope) - host = headers.get("host", "").split(":")[0] - is_valid_host = False - found_www_redirect = False - for pattern in self.allowed_hosts: - if host == pattern or ( - pattern.startswith("*") and host.endswith(pattern[1:]) - ): - is_valid_host = True - break - elif "www." + host == pattern: - found_www_redirect = True - - if is_valid_host: - await self.app(scope, receive, send) - else: - if found_www_redirect and self.www_redirect: - url = URL(scope=scope) - redirect_url = url.replace(netloc="www." + url.netloc) - response = RedirectResponse(url=str(redirect_url)) # type: Response - else: - response = PlainTextResponse("Invalid host header", status_code=400) - await response(scope, receive, send) diff --git a/env/lib/python3.8/site-packages/starlette/middleware/wsgi.py b/env/lib/python3.8/site-packages/starlette/middleware/wsgi.py deleted file mode 100644 index 8f7d9271..00000000 --- a/env/lib/python3.8/site-packages/starlette/middleware/wsgi.py +++ /dev/null @@ -1,143 +0,0 @@ -import asyncio -import io -import sys -import typing - -from starlette.concurrency import run_in_threadpool -from starlette.types import Message, Receive, Scope, Send - - -def build_environ(scope: Scope, body: bytes) -> dict: - """ - Builds a scope and request body into a WSGI environ object. - """ - environ = { - "REQUEST_METHOD": scope["method"], - "SCRIPT_NAME": scope.get("root_path", "").encode("utf8").decode("latin1"), - "PATH_INFO": scope["path"].encode("utf8").decode("latin1"), - "QUERY_STRING": scope["query_string"].decode("ascii"), - "SERVER_PROTOCOL": f"HTTP/{scope['http_version']}", - "wsgi.version": (1, 0), - "wsgi.url_scheme": scope.get("scheme", "http"), - "wsgi.input": io.BytesIO(body), - "wsgi.errors": sys.stdout, - "wsgi.multithread": True, - "wsgi.multiprocess": True, - "wsgi.run_once": False, - } - - # Get server name and port - required in WSGI, not in ASGI - server = scope.get("server") or ("localhost", 80) - environ["SERVER_NAME"] = server[0] - environ["SERVER_PORT"] = server[1] - - # Get client IP address - if scope.get("client"): - environ["REMOTE_ADDR"] = scope["client"][0] - - # Go through headers and make them into environ entries - for name, value in scope.get("headers", []): - name = name.decode("latin1") - if name == "content-length": - corrected_name = "CONTENT_LENGTH" - elif name == "content-type": - corrected_name = "CONTENT_TYPE" - else: - corrected_name = f"HTTP_{name}".upper().replace("-", "_") - # HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in case - value = value.decode("latin1") - if corrected_name in environ: - value = environ[corrected_name] + "," + value - environ[corrected_name] = value - return environ - - -class WSGIMiddleware: - def __init__(self, app: typing.Callable, workers: int = 10) -> None: - self.app = app - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - assert scope["type"] == "http" - responder = WSGIResponder(self.app, scope) - await responder(receive, send) - - -class WSGIResponder: - def __init__(self, app: typing.Callable, scope: Scope) -> None: - self.app = app - self.scope = scope - self.status = None - self.response_headers = None - self.send_event = asyncio.Event() - self.send_queue = [] # type: typing.List[typing.Optional[Message]] - self.loop = asyncio.get_event_loop() - self.response_started = False - self.exc_info = None # type: typing.Any - - async def __call__(self, receive: Receive, send: Send) -> None: - body = b"" - more_body = True - while more_body: - message = await receive() - body += message.get("body", b"") - more_body = message.get("more_body", False) - environ = build_environ(self.scope, body) - sender = None - try: - sender = self.loop.create_task(self.sender(send)) - await run_in_threadpool(self.wsgi, environ, self.start_response) - self.send_queue.append(None) - self.send_event.set() - await asyncio.wait_for(sender, None) - if self.exc_info is not None: - raise self.exc_info[0].with_traceback( - self.exc_info[1], self.exc_info[2] - ) - finally: - if sender and not sender.done(): - sender.cancel() # pragma: no cover - - async def sender(self, send: Send) -> None: - while True: - if self.send_queue: - message = self.send_queue.pop(0) - if message is None: - return - await send(message) - else: - await self.send_event.wait() - self.send_event.clear() - - def start_response( - self, - status: str, - response_headers: typing.List[typing.Tuple[str, str]], - exc_info: typing.Any = None, - ) -> None: - self.exc_info = exc_info - if not self.response_started: - self.response_started = True - status_code_string, _ = status.split(" ", 1) - status_code = int(status_code_string) - headers = [ - (name.strip().encode("ascii").lower(), value.strip().encode("ascii")) - for name, value in response_headers - ] - self.send_queue.append( - { - "type": "http.response.start", - "status": status_code, - "headers": headers, - } - ) - self.loop.call_soon_threadsafe(self.send_event.set) - - def wsgi(self, environ: dict, start_response: typing.Callable) -> None: - for chunk in self.app(environ, start_response): - self.send_queue.append( - {"type": "http.response.body", "body": chunk, "more_body": True} - ) - self.loop.call_soon_threadsafe(self.send_event.set) - - self.send_queue.append({"type": "http.response.body", "body": b""}) - self.loop.call_soon_threadsafe(self.send_event.set) diff --git a/env/lib/python3.8/site-packages/starlette/py.typed b/env/lib/python3.8/site-packages/starlette/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/starlette/requests.py b/env/lib/python3.8/site-packages/starlette/requests.py deleted file mode 100644 index 56a0c5a9..00000000 --- a/env/lib/python3.8/site-packages/starlette/requests.py +++ /dev/null @@ -1,273 +0,0 @@ -import asyncio -import json -import typing -from collections.abc import Mapping -from http import cookies as http_cookies - -from starlette.datastructures import URL, Address, FormData, Headers, QueryParams, State -from starlette.formparsers import FormParser, MultiPartParser -from starlette.types import Message, Receive, Scope, Send - -try: - from multipart.multipart import parse_options_header -except ImportError: # pragma: nocover - parse_options_header = None - - -SERVER_PUSH_HEADERS_TO_COPY = { - "accept", - "accept-encoding", - "accept-language", - "cache-control", - "user-agent", -} - - -def cookie_parser(cookie_string: str) -> typing.Dict[str, str]: - """ - This function parses a ``Cookie`` HTTP header into a dict of key/value pairs. - - It attempts to mimic browser cookie parsing behavior: browsers and web servers - frequently disregard the spec (RFC 6265) when setting and reading cookies, - so we attempt to suit the common scenarios here. - - This function has been adapted from Django 3.1.0. - Note: we are explicitly _NOT_ using `SimpleCookie.load` because it is based - on an outdated spec and will fail on lots of input we want to support - """ - cookie_dict: typing.Dict[str, str] = {} - for chunk in cookie_string.split(";"): - if "=" in chunk: - key, val = chunk.split("=", 1) - else: - # Assume an empty name per - # https://bugzilla.mozilla.org/show_bug.cgi?id=169091 - key, val = "", chunk - key, val = key.strip(), val.strip() - if key or val: - # unquote using Python's algorithm. - cookie_dict[key] = http_cookies._unquote(val) # type: ignore - return cookie_dict - - -class ClientDisconnect(Exception): - pass - - -class HTTPConnection(Mapping): - """ - A base class for incoming HTTP connections, that is used to provide - any functionality that is common to both `Request` and `WebSocket`. - """ - - def __init__(self, scope: Scope, receive: Receive = None) -> None: - assert scope["type"] in ("http", "websocket") - self.scope = scope - - def __getitem__(self, key: str) -> str: - return self.scope[key] - - def __iter__(self) -> typing.Iterator[str]: - return iter(self.scope) - - def __len__(self) -> int: - return len(self.scope) - - @property - def app(self) -> typing.Any: - return self.scope["app"] - - @property - def url(self) -> URL: - if not hasattr(self, "_url"): - self._url = URL(scope=self.scope) - return self._url - - @property - def base_url(self) -> URL: - if not hasattr(self, "_base_url"): - base_url_scope = dict(self.scope) - base_url_scope["path"] = "/" - base_url_scope["query_string"] = b"" - base_url_scope["root_path"] = base_url_scope.get( - "app_root_path", base_url_scope.get("root_path", "") - ) - self._base_url = URL(scope=base_url_scope) - return self._base_url - - @property - def headers(self) -> Headers: - if not hasattr(self, "_headers"): - self._headers = Headers(scope=self.scope) - return self._headers - - @property - def query_params(self) -> QueryParams: - if not hasattr(self, "_query_params"): - self._query_params = QueryParams(self.scope["query_string"]) - return self._query_params - - @property - def path_params(self) -> dict: - return self.scope.get("path_params", {}) - - @property - def cookies(self) -> typing.Dict[str, str]: - if not hasattr(self, "_cookies"): - cookies: typing.Dict[str, str] = {} - cookie_header = self.headers.get("cookie") - - if cookie_header: - cookies = cookie_parser(cookie_header) - self._cookies = cookies - return self._cookies - - @property - def client(self) -> Address: - host, port = self.scope.get("client") or (None, None) - return Address(host=host, port=port) - - @property - def session(self) -> dict: - assert ( - "session" in self.scope - ), "SessionMiddleware must be installed to access request.session" - return self.scope["session"] - - @property - def auth(self) -> typing.Any: - assert ( - "auth" in self.scope - ), "AuthenticationMiddleware must be installed to access request.auth" - return self.scope["auth"] - - @property - def user(self) -> typing.Any: - assert ( - "user" in self.scope - ), "AuthenticationMiddleware must be installed to access request.user" - return self.scope["user"] - - @property - def state(self) -> State: - if not hasattr(self, "_state"): - # Ensure 'state' has an empty dict if it's not already populated. - self.scope.setdefault("state", {}) - # Create a state instance with a reference to the dict in which it should store info - self._state = State(self.scope["state"]) - return self._state - - def url_for(self, name: str, **path_params: typing.Any) -> str: - router = self.scope["router"] - url_path = router.url_path_for(name, **path_params) - return url_path.make_absolute_url(base_url=self.base_url) - - -async def empty_receive() -> Message: - raise RuntimeError("Receive channel has not been made available") - - -async def empty_send(message: Message) -> None: - raise RuntimeError("Send channel has not been made available") - - -class Request(HTTPConnection): - def __init__( - self, scope: Scope, receive: Receive = empty_receive, send: Send = empty_send - ): - super().__init__(scope) - assert scope["type"] == "http" - self._receive = receive - self._send = send - self._stream_consumed = False - self._is_disconnected = False - - @property - def method(self) -> str: - return self.scope["method"] - - @property - def receive(self) -> Receive: - return self._receive - - async def stream(self) -> typing.AsyncGenerator[bytes, None]: - if hasattr(self, "_body"): - yield self._body - yield b"" - return - - if self._stream_consumed: - raise RuntimeError("Stream consumed") - - self._stream_consumed = True - while True: - message = await self._receive() - if message["type"] == "http.request": - body = message.get("body", b"") - if body: - yield body - if not message.get("more_body", False): - break - elif message["type"] == "http.disconnect": - self._is_disconnected = True - raise ClientDisconnect() - yield b"" - - async def body(self) -> bytes: - if not hasattr(self, "_body"): - chunks = [] - async for chunk in self.stream(): - chunks.append(chunk) - self._body = b"".join(chunks) - return self._body - - async def json(self) -> typing.Any: - if not hasattr(self, "_json"): - body = await self.body() - self._json = json.loads(body) - return self._json - - async def form(self) -> FormData: - if not hasattr(self, "_form"): - assert ( - parse_options_header is not None - ), "The `python-multipart` library must be installed to use form parsing." - content_type_header = self.headers.get("Content-Type") - content_type, options = parse_options_header(content_type_header) - if content_type == b"multipart/form-data": - multipart_parser = MultiPartParser(self.headers, self.stream()) - self._form = await multipart_parser.parse() - elif content_type == b"application/x-www-form-urlencoded": - form_parser = FormParser(self.headers, self.stream()) - self._form = await form_parser.parse() - else: - self._form = FormData() - return self._form - - async def close(self) -> None: - if hasattr(self, "_form"): - await self._form.close() - - async def is_disconnected(self) -> bool: - if not self._is_disconnected: - try: - message = await asyncio.wait_for(self._receive(), timeout=0.0000001) - except asyncio.TimeoutError: - message = {} - - if message.get("type") == "http.disconnect": - self._is_disconnected = True - - return self._is_disconnected - - async def send_push_promise(self, path: str) -> None: - if "http.response.push" in self.scope.get("extensions", {}): - raw_headers = [] - for name in SERVER_PUSH_HEADERS_TO_COPY: - for value in self.headers.getlist(name): - raw_headers.append( - (name.encode("latin-1"), value.encode("latin-1")) - ) - await self._send( - {"type": "http.response.push", "path": path, "headers": raw_headers} - ) diff --git a/env/lib/python3.8/site-packages/starlette/responses.py b/env/lib/python3.8/site-packages/starlette/responses.py deleted file mode 100644 index 1c9aaa11..00000000 --- a/env/lib/python3.8/site-packages/starlette/responses.py +++ /dev/null @@ -1,318 +0,0 @@ -import hashlib -import http.cookies -import inspect -import json -import os -import stat -import typing -from email.utils import formatdate -from mimetypes import guess_type -from urllib.parse import quote, quote_plus - -from starlette.background import BackgroundTask -from starlette.concurrency import iterate_in_threadpool, run_until_first_complete -from starlette.datastructures import URL, MutableHeaders -from starlette.types import Receive, Scope, Send - -# Workaround for adding samesite support to pre 3.8 python -http.cookies.Morsel._reserved["samesite"] = "SameSite" # type: ignore - -try: - import aiofiles - from aiofiles.os import stat as aio_stat -except ImportError: # pragma: nocover - aiofiles = None - aio_stat = None - -try: - import ujson -except ImportError: # pragma: nocover - ujson = None # type: ignore - - -class Response: - media_type = None - charset = "utf-8" - - def __init__( - self, - content: typing.Any = None, - status_code: int = 200, - headers: dict = None, - media_type: str = None, - background: BackgroundTask = None, - ) -> None: - self.status_code = status_code - if media_type is not None: - self.media_type = media_type - self.background = background - self.body = self.render(content) - self.init_headers(headers) - - def render(self, content: typing.Any) -> bytes: - if content is None: - return b"" - if isinstance(content, bytes): - return content - return content.encode(self.charset) - - def init_headers(self, headers: typing.Mapping[str, str] = None) -> None: - if headers is None: - raw_headers = [] # type: typing.List[typing.Tuple[bytes, bytes]] - populate_content_length = True - populate_content_type = True - else: - raw_headers = [ - (k.lower().encode("latin-1"), v.encode("latin-1")) - for k, v in headers.items() - ] - keys = [h[0] for h in raw_headers] - populate_content_length = b"content-length" not in keys - populate_content_type = b"content-type" not in keys - - body = getattr(self, "body", b"") - if body and populate_content_length: - content_length = str(len(body)) - raw_headers.append((b"content-length", content_length.encode("latin-1"))) - - content_type = self.media_type - if content_type is not None and populate_content_type: - if content_type.startswith("text/"): - content_type += "; charset=" + self.charset - raw_headers.append((b"content-type", content_type.encode("latin-1"))) - - self.raw_headers = raw_headers - - @property - def headers(self) -> MutableHeaders: - if not hasattr(self, "_headers"): - self._headers = MutableHeaders(raw=self.raw_headers) - return self._headers - - def set_cookie( - self, - key: str, - value: str = "", - max_age: int = None, - expires: int = None, - path: str = "/", - domain: str = None, - secure: bool = False, - httponly: bool = False, - samesite: str = "lax", - ) -> None: - cookie = http.cookies.SimpleCookie() # type: http.cookies.BaseCookie - cookie[key] = value - if max_age is not None: - cookie[key]["max-age"] = max_age - if expires is not None: - cookie[key]["expires"] = expires - if path is not None: - cookie[key]["path"] = path - if domain is not None: - cookie[key]["domain"] = domain - if secure: - cookie[key]["secure"] = True - if httponly: - cookie[key]["httponly"] = True - if samesite is not None: - assert samesite.lower() in [ - "strict", - "lax", - "none", - ], "samesite must be either 'strict', 'lax' or 'none'" - cookie[key]["samesite"] = samesite - cookie_val = cookie.output(header="").strip() - self.raw_headers.append((b"set-cookie", cookie_val.encode("latin-1"))) - - def delete_cookie(self, key: str, path: str = "/", domain: str = None) -> None: - self.set_cookie(key, expires=0, max_age=0, path=path, domain=domain) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - await send( - { - "type": "http.response.start", - "status": self.status_code, - "headers": self.raw_headers, - } - ) - await send({"type": "http.response.body", "body": self.body}) - - if self.background is not None: - await self.background() - - -class HTMLResponse(Response): - media_type = "text/html" - - -class PlainTextResponse(Response): - media_type = "text/plain" - - -class JSONResponse(Response): - media_type = "application/json" - - def render(self, content: typing.Any) -> bytes: - return json.dumps( - content, - ensure_ascii=False, - allow_nan=False, - indent=None, - separators=(",", ":"), - ).encode("utf-8") - - -class UJSONResponse(JSONResponse): - media_type = "application/json" - - def render(self, content: typing.Any) -> bytes: - assert ujson is not None, "ujson must be installed to use UJSONResponse" - return ujson.dumps(content, ensure_ascii=False).encode("utf-8") - - -class RedirectResponse(Response): - def __init__( - self, - url: typing.Union[str, URL], - status_code: int = 307, - headers: dict = None, - background: BackgroundTask = None, - ) -> None: - super().__init__( - content=b"", status_code=status_code, headers=headers, background=background - ) - self.headers["location"] = quote_plus(str(url), safe=":/%#?&=@[]!$&'()*+,;") - - -class StreamingResponse(Response): - def __init__( - self, - content: typing.Any, - status_code: int = 200, - headers: dict = None, - media_type: str = None, - background: BackgroundTask = None, - ) -> None: - if inspect.isasyncgen(content): - self.body_iterator = content - else: - self.body_iterator = iterate_in_threadpool(content) - self.status_code = status_code - self.media_type = self.media_type if media_type is None else media_type - self.background = background - self.init_headers(headers) - - async def listen_for_disconnect(self, receive: Receive) -> None: - while True: - message = await receive() - if message["type"] == "http.disconnect": - break - - async def stream_response(self, send: Send) -> None: - await send( - { - "type": "http.response.start", - "status": self.status_code, - "headers": self.raw_headers, - } - ) - async for chunk in self.body_iterator: - if not isinstance(chunk, bytes): - chunk = chunk.encode(self.charset) - await send({"type": "http.response.body", "body": chunk, "more_body": True}) - - await send({"type": "http.response.body", "body": b"", "more_body": False}) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - await run_until_first_complete( - (self.stream_response, {"send": send}), - (self.listen_for_disconnect, {"receive": receive}), - ) - - if self.background is not None: - await self.background() - - -class FileResponse(Response): - chunk_size = 4096 - - def __init__( - self, - path: str, - status_code: int = 200, - headers: dict = None, - media_type: str = None, - background: BackgroundTask = None, - filename: str = None, - stat_result: os.stat_result = None, - method: str = None, - ) -> None: - assert aiofiles is not None, "'aiofiles' must be installed to use FileResponse" - self.path = path - self.status_code = status_code - self.filename = filename - self.send_header_only = method is not None and method.upper() == "HEAD" - if media_type is None: - media_type = guess_type(filename or path)[0] or "text/plain" - self.media_type = media_type - self.background = background - self.init_headers(headers) - if self.filename is not None: - content_disposition_filename = quote(self.filename) - if content_disposition_filename != self.filename: - content_disposition = "attachment; filename*=utf-8''{}".format( - content_disposition_filename - ) - else: - content_disposition = 'attachment; filename="{}"'.format(self.filename) - self.headers.setdefault("content-disposition", content_disposition) - self.stat_result = stat_result - if stat_result is not None: - self.set_stat_headers(stat_result) - - def set_stat_headers(self, stat_result: os.stat_result) -> None: - content_length = str(stat_result.st_size) - last_modified = formatdate(stat_result.st_mtime, usegmt=True) - etag_base = str(stat_result.st_mtime) + "-" + str(stat_result.st_size) - etag = hashlib.md5(etag_base.encode()).hexdigest() - - self.headers.setdefault("content-length", content_length) - self.headers.setdefault("last-modified", last_modified) - self.headers.setdefault("etag", etag) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if self.stat_result is None: - try: - stat_result = await aio_stat(self.path) - self.set_stat_headers(stat_result) - except FileNotFoundError: - raise RuntimeError(f"File at path {self.path} does not exist.") - else: - mode = stat_result.st_mode - if not stat.S_ISREG(mode): - raise RuntimeError(f"File at path {self.path} is not a file.") - await send( - { - "type": "http.response.start", - "status": self.status_code, - "headers": self.raw_headers, - } - ) - if self.send_header_only: - await send({"type": "http.response.body", "body": b"", "more_body": False}) - else: - async with aiofiles.open(self.path, mode="rb") as file: - more_body = True - while more_body: - chunk = await file.read(self.chunk_size) - more_body = len(chunk) == self.chunk_size - await send( - { - "type": "http.response.body", - "body": chunk, - "more_body": more_body, - } - ) - if self.background is not None: - await self.background() diff --git a/env/lib/python3.8/site-packages/starlette/routing.py b/env/lib/python3.8/site-packages/starlette/routing.py deleted file mode 100644 index ac48169b..00000000 --- a/env/lib/python3.8/site-packages/starlette/routing.py +++ /dev/null @@ -1,672 +0,0 @@ -import asyncio -import inspect -import re -import traceback -import typing -from enum import Enum - -from starlette.concurrency import run_in_threadpool -from starlette.convertors import CONVERTOR_TYPES, Convertor -from starlette.datastructures import URL, Headers, URLPath -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.responses import PlainTextResponse, RedirectResponse -from starlette.types import ASGIApp, Receive, Scope, Send -from starlette.websockets import WebSocket, WebSocketClose - - -class NoMatchFound(Exception): - """ - Raised by `.url_for(name, **path_params)` and `.url_path_for(name, **path_params)` - if no matching route exists. - """ - - -class Match(Enum): - NONE = 0 - PARTIAL = 1 - FULL = 2 - - -def request_response(func: typing.Callable) -> ASGIApp: - """ - Takes a function or coroutine `func(request) -> response`, - and returns an ASGI application. - """ - is_coroutine = asyncio.iscoroutinefunction(func) - - async def app(scope: Scope, receive: Receive, send: Send) -> None: - request = Request(scope, receive=receive, send=send) - if is_coroutine: - response = await func(request) - else: - response = await run_in_threadpool(func, request) - await response(scope, receive, send) - - return app - - -def websocket_session(func: typing.Callable) -> ASGIApp: - """ - Takes a coroutine `func(session)`, and returns an ASGI application. - """ - # assert asyncio.iscoroutinefunction(func), "WebSocket endpoints must be async" - - async def app(scope: Scope, receive: Receive, send: Send) -> None: - session = WebSocket(scope, receive=receive, send=send) - await func(session) - - return app - - -def get_name(endpoint: typing.Callable) -> str: - if inspect.isfunction(endpoint) or inspect.isclass(endpoint): - return endpoint.__name__ - return endpoint.__class__.__name__ - - -def replace_params( - path: str, - param_convertors: typing.Dict[str, Convertor], - path_params: typing.Dict[str, str], -) -> typing.Tuple[str, dict]: - for key, value in list(path_params.items()): - if "{" + key + "}" in path: - convertor = param_convertors[key] - value = convertor.to_string(value) - path = path.replace("{" + key + "}", value) - path_params.pop(key) - return path, path_params - - -# Match parameters in URL paths, eg. '{param}', and '{param:int}' -PARAM_REGEX = re.compile("{([a-zA-Z_][a-zA-Z0-9_]*)(:[a-zA-Z_][a-zA-Z0-9_]*)?}") - - -def compile_path( - path: str, -) -> typing.Tuple[typing.Pattern, str, typing.Dict[str, Convertor]]: - """ - Given a path string, like: "/{username:str}", return a three-tuple - of (regex, format, {param_name:convertor}). - - regex: "/(?P[^/]+)" - format: "/{username}" - convertors: {"username": StringConvertor()} - """ - path_regex = "^" - path_format = "" - - idx = 0 - param_convertors = {} - for match in PARAM_REGEX.finditer(path): - param_name, convertor_type = match.groups("str") - convertor_type = convertor_type.lstrip(":") - assert ( - convertor_type in CONVERTOR_TYPES - ), f"Unknown path convertor '{convertor_type}'" - convertor = CONVERTOR_TYPES[convertor_type] - - path_regex += re.escape(path[idx : match.start()]) - path_regex += f"(?P<{param_name}>{convertor.regex})" - - path_format += path[idx : match.start()] - path_format += "{%s}" % param_name - - param_convertors[param_name] = convertor - - idx = match.end() - - path_regex += re.escape(path[idx:]) + "$" - path_format += path[idx:] - - return re.compile(path_regex), path_format, param_convertors - - -class BaseRoute: - def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]: - raise NotImplementedError() # pragma: no cover - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - raise NotImplementedError() # pragma: no cover - - async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: - raise NotImplementedError() # pragma: no cover - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - """ - A route may be used in isolation as a stand-alone ASGI app. - This is a somewhat contrived case, as they'll almost always be used - within a Router, but could be useful for some tooling and minimal apps. - """ - match, child_scope = self.matches(scope) - if match == Match.NONE: - if scope["type"] == "http": - response = PlainTextResponse("Not Found", status_code=404) - await response(scope, receive, send) - elif scope["type"] == "websocket": - websocket_close = WebSocketClose() - await websocket_close(scope, receive, send) - return - - scope.update(child_scope) - await self.handle(scope, receive, send) - - -class Route(BaseRoute): - def __init__( - self, - path: str, - endpoint: typing.Callable, - *, - methods: typing.List[str] = None, - name: str = None, - include_in_schema: bool = True, - ) -> None: - assert path.startswith("/"), "Routed paths must start with '/'" - self.path = path - self.endpoint = endpoint - self.name = get_name(endpoint) if name is None else name - self.include_in_schema = include_in_schema - - if inspect.isfunction(endpoint) or inspect.ismethod(endpoint): - # Endpoint is function or method. Treat it as `func(request) -> response`. - self.app = request_response(endpoint) - if methods is None: - methods = ["GET"] - else: - # Endpoint is a class. Treat it as ASGI. - self.app = endpoint - - if methods is None: - self.methods = None - else: - self.methods = set(method.upper() for method in methods) - if "GET" in self.methods: - self.methods.add("HEAD") - - self.path_regex, self.path_format, self.param_convertors = compile_path(path) - - def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]: - if scope["type"] == "http": - match = self.path_regex.match(scope["path"]) - if match: - matched_params = match.groupdict() - for key, value in matched_params.items(): - matched_params[key] = self.param_convertors[key].convert(value) - path_params = dict(scope.get("path_params", {})) - path_params.update(matched_params) - child_scope = {"endpoint": self.endpoint, "path_params": path_params} - if self.methods and scope["method"] not in self.methods: - return Match.PARTIAL, child_scope - else: - return Match.FULL, child_scope - return Match.NONE, {} - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - seen_params = set(path_params.keys()) - expected_params = set(self.param_convertors.keys()) - - if name != self.name or seen_params != expected_params: - raise NoMatchFound() - - path, remaining_params = replace_params( - self.path_format, self.param_convertors, path_params - ) - assert not remaining_params - return URLPath(path=path, protocol="http") - - async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: - if self.methods and scope["method"] not in self.methods: - if "app" in scope: - raise HTTPException(status_code=405) - else: - response = PlainTextResponse("Method Not Allowed", status_code=405) - await response(scope, receive, send) - else: - await self.app(scope, receive, send) - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, Route) - and self.path == other.path - and self.endpoint == other.endpoint - and self.methods == other.methods - ) - - -class WebSocketRoute(BaseRoute): - def __init__( - self, path: str, endpoint: typing.Callable, *, name: str = None - ) -> None: - assert path.startswith("/"), "Routed paths must start with '/'" - self.path = path - self.endpoint = endpoint - self.name = get_name(endpoint) if name is None else name - - if inspect.isfunction(endpoint) or inspect.ismethod(endpoint): - # Endpoint is function or method. Treat it as `func(websocket)`. - self.app = websocket_session(endpoint) - else: - # Endpoint is a class. Treat it as ASGI. - self.app = endpoint - - self.path_regex, self.path_format, self.param_convertors = compile_path(path) - - def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]: - if scope["type"] == "websocket": - match = self.path_regex.match(scope["path"]) - if match: - matched_params = match.groupdict() - for key, value in matched_params.items(): - matched_params[key] = self.param_convertors[key].convert(value) - path_params = dict(scope.get("path_params", {})) - path_params.update(matched_params) - child_scope = {"endpoint": self.endpoint, "path_params": path_params} - return Match.FULL, child_scope - return Match.NONE, {} - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - seen_params = set(path_params.keys()) - expected_params = set(self.param_convertors.keys()) - - if name != self.name or seen_params != expected_params: - raise NoMatchFound() - - path, remaining_params = replace_params( - self.path_format, self.param_convertors, path_params - ) - assert not remaining_params - return URLPath(path=path, protocol="websocket") - - async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: - await self.app(scope, receive, send) - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, WebSocketRoute) - and self.path == other.path - and self.endpoint == other.endpoint - ) - - -class Mount(BaseRoute): - def __init__( - self, - path: str, - app: ASGIApp = None, - routes: typing.Sequence[BaseRoute] = None, - name: str = None, - ) -> None: - assert path == "" or path.startswith("/"), "Routed paths must start with '/'" - assert ( - app is not None or routes is not None - ), "Either 'app=...', or 'routes=' must be specified" - self.path = path.rstrip("/") - if app is not None: - self.app = app # type: ASGIApp - else: - self.app = Router(routes=routes) - self.name = name - self.path_regex, self.path_format, self.param_convertors = compile_path( - self.path + "/{path:path}" - ) - - @property - def routes(self) -> typing.List[BaseRoute]: - return getattr(self.app, "routes", None) - - def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]: - if scope["type"] in ("http", "websocket"): - path = scope["path"] - match = self.path_regex.match(path) - if match: - matched_params = match.groupdict() - for key, value in matched_params.items(): - matched_params[key] = self.param_convertors[key].convert(value) - remaining_path = "/" + matched_params.pop("path") - matched_path = path[: -len(remaining_path)] - path_params = dict(scope.get("path_params", {})) - path_params.update(matched_params) - root_path = scope.get("root_path", "") - child_scope = { - "path_params": path_params, - "app_root_path": scope.get("app_root_path", root_path), - "root_path": root_path + matched_path, - "path": remaining_path, - "endpoint": self.app, - } - return Match.FULL, child_scope - return Match.NONE, {} - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - if self.name is not None and name == self.name and "path" in path_params: - # 'name' matches "". - path_params["path"] = path_params["path"].lstrip("/") - path, remaining_params = replace_params( - self.path_format, self.param_convertors, path_params - ) - if not remaining_params: - return URLPath(path=path) - elif self.name is None or name.startswith(self.name + ":"): - if self.name is None: - # No mount name. - remaining_name = name - else: - # 'name' matches ":". - remaining_name = name[len(self.name) + 1 :] - path_kwarg = path_params.get("path") - path_params["path"] = "" - path_prefix, remaining_params = replace_params( - self.path_format, self.param_convertors, path_params - ) - if path_kwarg is not None: - remaining_params["path"] = path_kwarg - for route in self.routes or []: - try: - url = route.url_path_for(remaining_name, **remaining_params) - return URLPath( - path=path_prefix.rstrip("/") + str(url), protocol=url.protocol - ) - except NoMatchFound: - pass - raise NoMatchFound() - - async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: - await self.app(scope, receive, send) - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, Mount) - and self.path == other.path - and self.app == other.app - ) - - -class Host(BaseRoute): - def __init__(self, host: str, app: ASGIApp, name: str = None) -> None: - self.host = host - self.app = app - self.name = name - self.host_regex, self.host_format, self.param_convertors = compile_path(host) - - @property - def routes(self) -> typing.List[BaseRoute]: - return getattr(self.app, "routes", None) - - def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]: - if scope["type"] in ("http", "websocket"): - headers = Headers(scope=scope) - host = headers.get("host", "").split(":")[0] - match = self.host_regex.match(host) - if match: - matched_params = match.groupdict() - for key, value in matched_params.items(): - matched_params[key] = self.param_convertors[key].convert(value) - path_params = dict(scope.get("path_params", {})) - path_params.update(matched_params) - child_scope = {"path_params": path_params, "endpoint": self.app} - return Match.FULL, child_scope - return Match.NONE, {} - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - if self.name is not None and name == self.name and "path" in path_params: - # 'name' matches "". - path = path_params.pop("path") - host, remaining_params = replace_params( - self.host_format, self.param_convertors, path_params - ) - if not remaining_params: - return URLPath(path=path, host=host) - elif self.name is None or name.startswith(self.name + ":"): - if self.name is None: - # No mount name. - remaining_name = name - else: - # 'name' matches ":". - remaining_name = name[len(self.name) + 1 :] - host, remaining_params = replace_params( - self.host_format, self.param_convertors, path_params - ) - for route in self.routes or []: - try: - url = route.url_path_for(remaining_name, **remaining_params) - return URLPath(path=str(url), protocol=url.protocol, host=host) - except NoMatchFound: - pass - raise NoMatchFound() - - async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: - await self.app(scope, receive, send) - - def __eq__(self, other: typing.Any) -> bool: - return ( - isinstance(other, Host) - and self.host == other.host - and self.app == other.app - ) - - -class Router: - def __init__( - self, - routes: typing.Sequence[BaseRoute] = None, - redirect_slashes: bool = True, - default: ASGIApp = None, - on_startup: typing.Sequence[typing.Callable] = None, - on_shutdown: typing.Sequence[typing.Callable] = None, - lifespan: typing.Callable[[typing.Any], typing.AsyncGenerator] = None, - ) -> None: - self.routes = [] if routes is None else list(routes) - self.redirect_slashes = redirect_slashes - self.default = self.not_found if default is None else default - self.on_startup = [] if on_startup is None else list(on_startup) - self.on_shutdown = [] if on_shutdown is None else list(on_shutdown) - - async def default_lifespan(app: typing.Any) -> typing.AsyncGenerator: - await self.startup() - yield - await self.shutdown() - - self.lifespan_context = default_lifespan if lifespan is None else lifespan - - async def not_found(self, scope: Scope, receive: Receive, send: Send) -> None: - if scope["type"] == "websocket": - websocket_close = WebSocketClose() - await websocket_close(scope, receive, send) - return - - # If we're running inside a starlette application then raise an - # exception, so that the configurable exception handler can deal with - # returning the response. For plain ASGI apps, just return the response. - if "app" in scope: - raise HTTPException(status_code=404) - else: - response = PlainTextResponse("Not Found", status_code=404) - await response(scope, receive, send) - - def url_path_for(self, name: str, **path_params: str) -> URLPath: - for route in self.routes: - try: - return route.url_path_for(name, **path_params) - except NoMatchFound: - pass - raise NoMatchFound() - - async def startup(self) -> None: - """ - Run any `.on_startup` event handlers. - """ - for handler in self.on_startup: - if asyncio.iscoroutinefunction(handler): - await handler() - else: - handler() - - async def shutdown(self) -> None: - """ - Run any `.on_shutdown` event handlers. - """ - for handler in self.on_shutdown: - if asyncio.iscoroutinefunction(handler): - await handler() - else: - handler() - - async def lifespan(self, scope: Scope, receive: Receive, send: Send) -> None: - """ - Handle ASGI lifespan messages, which allows us to manage application - startup and shutdown events. - """ - first = True - app = scope.get("app") - message = await receive() - try: - if inspect.isasyncgenfunction(self.lifespan_context): - async for item in self.lifespan_context(app): - assert first, "Lifespan context yielded multiple times." - first = False - await send({"type": "lifespan.startup.complete"}) - message = await receive() - else: - for item in self.lifespan_context(app): # type: ignore - assert first, "Lifespan context yielded multiple times." - first = False - await send({"type": "lifespan.startup.complete"}) - message = await receive() - except BaseException: - if first: - exc_text = traceback.format_exc() - await send({"type": "lifespan.startup.failed", "message": exc_text}) - raise - else: - await send({"type": "lifespan.shutdown.complete"}) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - """ - The main entry point to the Router class. - """ - assert scope["type"] in ("http", "websocket", "lifespan") - - if "router" not in scope: - scope["router"] = self - - if scope["type"] == "lifespan": - await self.lifespan(scope, receive, send) - return - - partial = None - - for route in self.routes: - # Determine if any route matches the incoming scope, - # and hand over to the matching route if found. - match, child_scope = route.matches(scope) - if match == Match.FULL: - scope.update(child_scope) - await route.handle(scope, receive, send) - return - elif match == Match.PARTIAL and partial is None: - partial = route - partial_scope = child_scope - - if partial is not None: - #  Handle partial matches. These are cases where an endpoint is - # able to handle the request, but is not a preferred option. - # We use this in particular to deal with "405 Method Not Allowed". - scope.update(partial_scope) - await partial.handle(scope, receive, send) - return - - if scope["type"] == "http" and self.redirect_slashes and scope["path"] != "/": - redirect_scope = dict(scope) - if scope["path"].endswith("/"): - redirect_scope["path"] = redirect_scope["path"].rstrip("/") - else: - redirect_scope["path"] = redirect_scope["path"] + "/" - - for route in self.routes: - match, child_scope = route.matches(redirect_scope) - if match != Match.NONE: - redirect_url = URL(scope=redirect_scope) - response = RedirectResponse(url=str(redirect_url)) - await response(scope, receive, send) - return - - await self.default(scope, receive, send) - - def __eq__(self, other: typing.Any) -> bool: - return isinstance(other, Router) and self.routes == other.routes - - # The following usages are now discouraged in favour of configuration - #  during Router.__init__(...) - def mount(self, path: str, app: ASGIApp, name: str = None) -> None: - route = Mount(path, app=app, name=name) - self.routes.append(route) - - def host(self, host: str, app: ASGIApp, name: str = None) -> None: - route = Host(host, app=app, name=name) - self.routes.append(route) - - def add_route( - self, - path: str, - endpoint: typing.Callable, - methods: typing.List[str] = None, - name: str = None, - include_in_schema: bool = True, - ) -> None: - route = Route( - path, - endpoint=endpoint, - methods=methods, - name=name, - include_in_schema=include_in_schema, - ) - self.routes.append(route) - - def add_websocket_route( - self, path: str, endpoint: typing.Callable, name: str = None - ) -> None: - route = WebSocketRoute(path, endpoint=endpoint, name=name) - self.routes.append(route) - - def route( - self, - path: str, - methods: typing.List[str] = None, - name: str = None, - include_in_schema: bool = True, - ) -> typing.Callable: - def decorator(func: typing.Callable) -> typing.Callable: - self.add_route( - path, - func, - methods=methods, - name=name, - include_in_schema=include_in_schema, - ) - return func - - return decorator - - def websocket_route(self, path: str, name: str = None) -> typing.Callable: - def decorator(func: typing.Callable) -> typing.Callable: - self.add_websocket_route(path, func, name=name) - return func - - return decorator - - def add_event_handler(self, event_type: str, func: typing.Callable) -> None: - assert event_type in ("startup", "shutdown") - - if event_type == "startup": - self.on_startup.append(func) - else: - self.on_shutdown.append(func) - - def on_event(self, event_type: str) -> typing.Callable: - def decorator(func: typing.Callable) -> typing.Callable: - self.add_event_handler(event_type, func) - return func - - return decorator diff --git a/env/lib/python3.8/site-packages/starlette/schemas.py b/env/lib/python3.8/site-packages/starlette/schemas.py deleted file mode 100644 index 6ca764fd..00000000 --- a/env/lib/python3.8/site-packages/starlette/schemas.py +++ /dev/null @@ -1,135 +0,0 @@ -import inspect -import typing - -from starlette.requests import Request -from starlette.responses import Response -from starlette.routing import BaseRoute, Mount, Route - -try: - import yaml -except ImportError: # pragma: nocover - yaml = None # type: ignore - - -class OpenAPIResponse(Response): - media_type = "application/vnd.oai.openapi" - - def render(self, content: typing.Any) -> bytes: - assert yaml is not None, "`pyyaml` must be installed to use OpenAPIResponse." - assert isinstance( - content, dict - ), "The schema passed to OpenAPIResponse should be a dictionary." - return yaml.dump(content, default_flow_style=False).encode("utf-8") - - -class EndpointInfo(typing.NamedTuple): - path: str - http_method: str - func: typing.Callable - - -class BaseSchemaGenerator: - def get_schema(self, routes: typing.List[BaseRoute]) -> dict: - raise NotImplementedError() # pragma: no cover - - def get_endpoints( - self, routes: typing.List[BaseRoute] - ) -> typing.List[EndpointInfo]: - """ - Given the routes, yields the following information: - - - path - eg: /users/ - - http_method - one of 'get', 'post', 'put', 'patch', 'delete', 'options' - - func - method ready to extract the docstring - """ - endpoints_info: list = [] - - for route in routes: - if isinstance(route, Mount): - routes = route.routes or [] - sub_endpoints = [ - EndpointInfo( - path="".join((route.path, sub_endpoint.path)), - http_method=sub_endpoint.http_method, - func=sub_endpoint.func, - ) - for sub_endpoint in self.get_endpoints(routes) - ] - endpoints_info.extend(sub_endpoints) - - elif not isinstance(route, Route) or not route.include_in_schema: - continue - - elif inspect.isfunction(route.endpoint) or inspect.ismethod(route.endpoint): - for method in route.methods or ["GET"]: - if method == "HEAD": - continue - endpoints_info.append( - EndpointInfo(route.path, method.lower(), route.endpoint) - ) - else: - for method in ["get", "post", "put", "patch", "delete", "options"]: - if not hasattr(route.endpoint, method): - continue - func = getattr(route.endpoint, method) - endpoints_info.append( - EndpointInfo(route.path, method.lower(), func) - ) - - return endpoints_info - - def parse_docstring(self, func_or_method: typing.Callable) -> dict: - """ - Given a function, parse the docstring as YAML and return a dictionary of info. - """ - docstring = func_or_method.__doc__ - if not docstring: - return {} - - assert yaml is not None, "`pyyaml` must be installed to use parse_docstring." - - # We support having regular docstrings before the schema - # definition. Here we return just the schema part from - # the docstring. - docstring = docstring.split("---")[-1] - - parsed = yaml.safe_load(docstring) - - if not isinstance(parsed, dict): - # A regular docstring (not yaml formatted) can return - # a simple string here, which wouldn't follow the schema. - return {} - - return parsed - - def OpenAPIResponse(self, request: Request) -> Response: - routes = request.app.routes - schema = self.get_schema(routes=routes) - return OpenAPIResponse(schema) - - -class SchemaGenerator(BaseSchemaGenerator): - def __init__(self, base_schema: dict) -> None: - self.base_schema = base_schema - - def get_schema(self, routes: typing.List[BaseRoute]) -> dict: - schema = dict(self.base_schema) - schema.setdefault("paths", {}) - endpoints_info = self.get_endpoints(routes) - - for endpoint in endpoints_info: - - parsed = self.parse_docstring(endpoint.func) - - if not parsed: - continue - - if endpoint.path not in schema["paths"]: - schema["paths"][endpoint.path] = {} - - schema["paths"][endpoint.path][endpoint.http_method] = parsed - - return schema diff --git a/env/lib/python3.8/site-packages/starlette/staticfiles.py b/env/lib/python3.8/site-packages/starlette/staticfiles.py deleted file mode 100644 index 22b9d3ae..00000000 --- a/env/lib/python3.8/site-packages/starlette/staticfiles.py +++ /dev/null @@ -1,219 +0,0 @@ -import importlib.util -import os -import stat -import typing -from email.utils import parsedate - -from aiofiles.os import stat as aio_stat - -from starlette.datastructures import URL, Headers -from starlette.responses import ( - FileResponse, - PlainTextResponse, - RedirectResponse, - Response, -) -from starlette.types import Receive, Scope, Send - - -class NotModifiedResponse(Response): - NOT_MODIFIED_HEADERS = ( - "cache-control", - "content-location", - "date", - "etag", - "expires", - "vary", - ) - - def __init__(self, headers: Headers): - super().__init__( - status_code=304, - headers={ - name: value - for name, value in headers.items() - if name in self.NOT_MODIFIED_HEADERS - }, - ) - - -class StaticFiles: - def __init__( - self, - *, - directory: str = None, - packages: typing.List[str] = None, - html: bool = False, - check_dir: bool = True, - ) -> None: - self.directory = directory - self.packages = packages - self.all_directories = self.get_directories(directory, packages) - self.html = html - self.config_checked = False - if check_dir and directory is not None and not os.path.isdir(directory): - raise RuntimeError(f"Directory '{directory}' does not exist") - - def get_directories( - self, directory: str = None, packages: typing.List[str] = None - ) -> typing.List[str]: - """ - Given `directory` and `packages` arguments, return a list of all the - directories that should be used for serving static files from. - """ - directories = [] - if directory is not None: - directories.append(directory) - - for package in packages or []: - spec = importlib.util.find_spec(package) - assert spec is not None, f"Package {package!r} could not be found." - assert ( - spec.origin is not None - ), f"Directory 'statics' in package {package!r} could not be found." - directory = os.path.normpath(os.path.join(spec.origin, "..", "statics")) - assert os.path.isdir( - directory - ), f"Directory 'statics' in package {package!r} could not be found." - directories.append(directory) - - return directories - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - """ - The ASGI entry point. - """ - assert scope["type"] == "http" - - if not self.config_checked: - await self.check_config() - self.config_checked = True - - path = self.get_path(scope) - response = await self.get_response(path, scope) - await response(scope, receive, send) - - def get_path(self, scope: Scope) -> str: - """ - Given the ASGI scope, return the `path` string to serve up, - with OS specific path seperators, and any '..', '.' components removed. - """ - return os.path.normpath(os.path.join(*scope["path"].split("/"))) - - async def get_response(self, path: str, scope: Scope) -> Response: - """ - Returns an HTTP response, given the incoming path, method and request headers. - """ - if scope["method"] not in ("GET", "HEAD"): - return PlainTextResponse("Method Not Allowed", status_code=405) - - full_path, stat_result = await self.lookup_path(path) - - if stat_result and stat.S_ISREG(stat_result.st_mode): - # We have a static file to serve. - return self.file_response(full_path, stat_result, scope) - - elif stat_result and stat.S_ISDIR(stat_result.st_mode) and self.html: - # We're in HTML mode, and have got a directory URL. - # Check if we have 'index.html' file to serve. - index_path = os.path.join(path, "index.html") - full_path, stat_result = await self.lookup_path(index_path) - if stat_result is not None and stat.S_ISREG(stat_result.st_mode): - if not scope["path"].endswith("/"): - # Directory URLs should redirect to always end in "/". - url = URL(scope=scope) - url = url.replace(path=url.path + "/") - return RedirectResponse(url=url) - return self.file_response(full_path, stat_result, scope) - - if self.html: - # Check for '404.html' if we're in HTML mode. - full_path, stat_result = await self.lookup_path("404.html") - if stat_result is not None and stat.S_ISREG(stat_result.st_mode): - return self.file_response( - full_path, stat_result, scope, status_code=404 - ) - - return PlainTextResponse("Not Found", status_code=404) - - async def lookup_path( - self, path: str - ) -> typing.Tuple[str, typing.Optional[os.stat_result]]: - for directory in self.all_directories: - full_path = os.path.realpath(os.path.join(directory, path)) - directory = os.path.realpath(directory) - if os.path.commonprefix([full_path, directory]) != directory: - # Don't allow misbehaving clients to break out of the static files directory. - continue - try: - stat_result = await aio_stat(full_path) - return (full_path, stat_result) - except FileNotFoundError: - pass - return ("", None) - - def file_response( - self, - full_path: str, - stat_result: os.stat_result, - scope: Scope, - status_code: int = 200, - ) -> Response: - method = scope["method"] - request_headers = Headers(scope=scope) - - response = FileResponse( - full_path, status_code=status_code, stat_result=stat_result, method=method - ) - if self.is_not_modified(response.headers, request_headers): - return NotModifiedResponse(response.headers) - return response - - async def check_config(self) -> None: - """ - Perform a one-off configuration check that StaticFiles is actually - pointed at a directory, so that we can raise loud errors rather than - just returning 404 responses. - """ - if self.directory is None: - return - - try: - stat_result = await aio_stat(self.directory) - except FileNotFoundError: - raise RuntimeError( - f"StaticFiles directory '{self.directory}' does not exist." - ) - if not (stat.S_ISDIR(stat_result.st_mode) or stat.S_ISLNK(stat_result.st_mode)): - raise RuntimeError( - f"StaticFiles path '{self.directory}' is not a directory." - ) - - def is_not_modified( - self, response_headers: Headers, request_headers: Headers - ) -> bool: - """ - Given the request and response headers, return `True` if an HTTP - "Not Modified" response could be returned instead. - """ - try: - if_none_match = request_headers["if-none-match"] - etag = response_headers["etag"] - if if_none_match == etag: - return True - except KeyError: - pass - - try: - if_modified_since = parsedate(request_headers["if-modified-since"]) - last_modified = parsedate(response_headers["last-modified"]) - if ( - if_modified_since is not None - and last_modified is not None - and if_modified_since >= last_modified - ): - return True - except KeyError: - pass - - return False diff --git a/env/lib/python3.8/site-packages/starlette/status.py b/env/lib/python3.8/site-packages/starlette/status.py deleted file mode 100644 index 0efaab74..00000000 --- a/env/lib/python3.8/site-packages/starlette/status.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -HTTP codes -See RFC 2616 - https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html -And RFC 6585 - https://tools.ietf.org/html/rfc6585 -And RFC 4918 - https://tools.ietf.org/html/rfc4918 -And RFC 8470 - https://tools.ietf.org/html/rfc8470 -""" -HTTP_100_CONTINUE = 100 -HTTP_101_SWITCHING_PROTOCOLS = 101 -HTTP_200_OK = 200 -HTTP_201_CREATED = 201 -HTTP_202_ACCEPTED = 202 -HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203 -HTTP_204_NO_CONTENT = 204 -HTTP_205_RESET_CONTENT = 205 -HTTP_206_PARTIAL_CONTENT = 206 -HTTP_207_MULTI_STATUS = 207 -HTTP_300_MULTIPLE_CHOICES = 300 -HTTP_301_MOVED_PERMANENTLY = 301 -HTTP_302_FOUND = 302 -HTTP_303_SEE_OTHER = 303 -HTTP_304_NOT_MODIFIED = 304 -HTTP_305_USE_PROXY = 305 -HTTP_306_RESERVED = 306 -HTTP_307_TEMPORARY_REDIRECT = 307 -HTTP_400_BAD_REQUEST = 400 -HTTP_401_UNAUTHORIZED = 401 -HTTP_402_PAYMENT_REQUIRED = 402 -HTTP_403_FORBIDDEN = 403 -HTTP_404_NOT_FOUND = 404 -HTTP_405_METHOD_NOT_ALLOWED = 405 -HTTP_406_NOT_ACCEPTABLE = 406 -HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407 -HTTP_408_REQUEST_TIMEOUT = 408 -HTTP_409_CONFLICT = 409 -HTTP_410_GONE = 410 -HTTP_411_LENGTH_REQUIRED = 411 -HTTP_412_PRECONDITION_FAILED = 412 -HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413 -HTTP_414_REQUEST_URI_TOO_LONG = 414 -HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415 -HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416 -HTTP_417_EXPECTATION_FAILED = 417 -HTTP_422_UNPROCESSABLE_ENTITY = 422 -HTTP_423_LOCKED = 423 -HTTP_424_FAILED_DEPENDENCY = 424 -HTTP_425_TOO_EARLY = 425 -HTTP_428_PRECONDITION_REQUIRED = 428 -HTTP_429_TOO_MANY_REQUESTS = 429 -HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 -HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451 -HTTP_500_INTERNAL_SERVER_ERROR = 500 -HTTP_501_NOT_IMPLEMENTED = 501 -HTTP_502_BAD_GATEWAY = 502 -HTTP_503_SERVICE_UNAVAILABLE = 503 -HTTP_504_GATEWAY_TIMEOUT = 504 -HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505 -HTTP_507_INSUFFICIENT_STORAGE = 507 -HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 - - -""" -WebSocket codes -https://www.iana.org/assignments/websocket/websocket.xml#close-code-number -https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent -""" -WS_1000_NORMAL_CLOSURE = 1000 -WS_1001_GOING_AWAY = 1001 -WS_1002_PROTOCOL_ERROR = 1002 -WS_1003_UNSUPPORTED_DATA = 1003 -WS_1004_NO_STATUS_RCVD = 1004 -WS_1005_ABNORMAL_CLOSURE = 1005 -WS_1007_INVALID_FRAME_PAYLOAD_DATA = 1007 -WS_1008_POLICY_VIOLATION = 1008 -WS_1009_MESSAGE_TOO_BIG = 1009 -WS_1010_MANDATORY_EXT = 1010 -WS_1011_INTERNAL_ERROR = 1011 -WS_1012_SERVICE_RESTART = 1012 -WS_1013_TRY_AGAIN_LATER = 1013 -WS_1014_BAD_GATEWAY = 1014 -WS_1015_TLS_HANDSHAKE = 1015 diff --git a/env/lib/python3.8/site-packages/starlette/templating.py b/env/lib/python3.8/site-packages/starlette/templating.py deleted file mode 100644 index 631b6bfe..00000000 --- a/env/lib/python3.8/site-packages/starlette/templating.py +++ /dev/null @@ -1,88 +0,0 @@ -import typing - -from starlette.background import BackgroundTask -from starlette.responses import Response -from starlette.types import Receive, Scope, Send - -try: - import jinja2 -except ImportError: # pragma: nocover - jinja2 = None # type: ignore - - -class _TemplateResponse(Response): - media_type = "text/html" - - def __init__( - self, - template: typing.Any, - context: dict, - status_code: int = 200, - headers: dict = None, - media_type: str = None, - background: BackgroundTask = None, - ): - self.template = template - self.context = context - content = template.render(context) - super().__init__(content, status_code, headers, media_type, background) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - request = self.context.get("request", {}) - extensions = request.get("extensions", {}) - if "http.response.template" in extensions: - await send( - { - "type": "http.response.template", - "template": self.template, - "context": self.context, - } - ) - await super().__call__(scope, receive, send) - - -class Jinja2Templates: - """ - templates = Jinja2Templates("templates") - - return templates.TemplateResponse("index.html", {"request": request}) - """ - - def __init__(self, directory: str) -> None: - assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates" - self.env = self.get_env(directory) - - def get_env(self, directory: str) -> "jinja2.Environment": - @jinja2.contextfunction - def url_for(context: dict, name: str, **path_params: typing.Any) -> str: - request = context["request"] - return request.url_for(name, **path_params) - - loader = jinja2.FileSystemLoader(directory) - env = jinja2.Environment(loader=loader, autoescape=True) - env.globals["url_for"] = url_for - return env - - def get_template(self, name: str) -> "jinja2.Template": - return self.env.get_template(name) - - def TemplateResponse( - self, - name: str, - context: dict, - status_code: int = 200, - headers: dict = None, - media_type: str = None, - background: BackgroundTask = None, - ) -> _TemplateResponse: - if "request" not in context: - raise ValueError('context must include a "request" key') - template = self.get_template(name) - return _TemplateResponse( - template, - context, - status_code=status_code, - headers=headers, - media_type=media_type, - background=background, - ) diff --git a/env/lib/python3.8/site-packages/starlette/testclient.py b/env/lib/python3.8/site-packages/starlette/testclient.py deleted file mode 100644 index a4c7dffc..00000000 --- a/env/lib/python3.8/site-packages/starlette/testclient.py +++ /dev/null @@ -1,491 +0,0 @@ -import asyncio -import http -import inspect -import io -import json -import queue -import threading -import types -import typing -from urllib.parse import unquote, urljoin, urlsplit - -import requests - -from starlette.types import Message, Receive, Scope, Send -from starlette.websockets import WebSocketDisconnect - -# Annotations for `Session.request()` -Cookies = typing.Union[ - typing.MutableMapping[str, str], requests.cookies.RequestsCookieJar -] -Params = typing.Union[bytes, typing.MutableMapping[str, str]] -DataType = typing.Union[bytes, typing.MutableMapping[str, str], typing.IO] -TimeOut = typing.Union[float, typing.Tuple[float, float]] -FileType = typing.MutableMapping[str, typing.IO] -AuthType = typing.Union[ - typing.Tuple[str, str], - requests.auth.AuthBase, - typing.Callable[[requests.Request], requests.Request], -] - - -ASGIInstance = typing.Callable[[Receive, Send], typing.Awaitable[None]] -ASGI2App = typing.Callable[[Scope], ASGIInstance] -ASGI3App = typing.Callable[[Scope, Receive, Send], typing.Awaitable[None]] - - -class _HeaderDict(requests.packages.urllib3._collections.HTTPHeaderDict): - def get_all(self, key: str, default: str) -> str: - return self.getheaders(key) - - -class _MockOriginalResponse: - """ - We have to jump through some hoops to present the response as if - it was made using urllib3. - """ - - def __init__(self, headers: typing.List[typing.Tuple[bytes, bytes]]) -> None: - self.msg = _HeaderDict(headers) - self.closed = False - - def isclosed(self) -> bool: - return self.closed - - -class _Upgrade(Exception): - def __init__(self, session: "WebSocketTestSession") -> None: - self.session = session - - -def _get_reason_phrase(status_code: int) -> str: - try: - return http.HTTPStatus(status_code).phrase - except ValueError: - return "" - - -def _is_asgi3(app: typing.Union[ASGI2App, ASGI3App]) -> bool: - if inspect.isclass(app): - return hasattr(app, "__await__") - elif inspect.isfunction(app): - return asyncio.iscoroutinefunction(app) - call = getattr(app, "__call__", None) - return asyncio.iscoroutinefunction(call) - - -class _WrapASGI2: - """ - Provide an ASGI3 interface onto an ASGI2 app. - """ - - def __init__(self, app: ASGI2App) -> None: - self.app = app - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - instance = self.app(scope) - await instance(receive, send) - - -class _ASGIAdapter(requests.adapters.HTTPAdapter): - def __init__( - self, app: ASGI3App, raise_server_exceptions: bool = True, root_path: str = "" - ) -> None: - self.app = app - self.raise_server_exceptions = raise_server_exceptions - self.root_path = root_path - - def send( - self, request: requests.PreparedRequest, *args: typing.Any, **kwargs: typing.Any - ) -> requests.Response: - scheme, netloc, path, query, fragment = ( - str(item) for item in urlsplit(request.url) - ) - - default_port = {"http": 80, "ws": 80, "https": 443, "wss": 443}[scheme] - - if ":" in netloc: - host, port_string = netloc.split(":", 1) - port = int(port_string) - else: - host = netloc - port = default_port - - # Include the 'host' header. - if "host" in request.headers: - headers = [] # type: typing.List[typing.Tuple[bytes, bytes]] - elif port == default_port: - headers = [(b"host", host.encode())] - else: - headers = [(b"host", (f"{host}:{port}").encode())] - - # Include other request headers. - headers += [ - (key.lower().encode(), value.encode()) - for key, value in request.headers.items() - ] - - if scheme in {"ws", "wss"}: - subprotocol = request.headers.get("sec-websocket-protocol", None) - if subprotocol is None: - subprotocols = [] # type: typing.Sequence[str] - else: - subprotocols = [value.strip() for value in subprotocol.split(",")] - scope = { - "type": "websocket", - "path": unquote(path), - "root_path": self.root_path, - "scheme": scheme, - "query_string": query.encode(), - "headers": headers, - "client": ["testclient", 50000], - "server": [host, port], - "subprotocols": subprotocols, - } - session = WebSocketTestSession(self.app, scope) - raise _Upgrade(session) - - scope = { - "type": "http", - "http_version": "1.1", - "method": request.method, - "path": unquote(path), - "root_path": self.root_path, - "scheme": scheme, - "query_string": query.encode(), - "headers": headers, - "client": ["testclient", 50000], - "server": [host, port], - "extensions": {"http.response.template": {}}, - } - - request_complete = False - response_started = False - response_complete = False - raw_kwargs = {"body": io.BytesIO()} # type: typing.Dict[str, typing.Any] - template = None - context = None - - async def receive() -> Message: - nonlocal request_complete, response_complete - - if request_complete: - while not response_complete: - await asyncio.sleep(0.0001) - return {"type": "http.disconnect"} - - body = request.body - if isinstance(body, str): - body_bytes = body.encode("utf-8") # type: bytes - elif body is None: - body_bytes = b"" - elif isinstance(body, types.GeneratorType): - try: - chunk = body.send(None) - if isinstance(chunk, str): - chunk = chunk.encode("utf-8") - return {"type": "http.request", "body": chunk, "more_body": True} - except StopIteration: - request_complete = True - return {"type": "http.request", "body": b""} - else: - body_bytes = body - - request_complete = True - return {"type": "http.request", "body": body_bytes} - - async def send(message: Message) -> None: - nonlocal raw_kwargs, response_started, response_complete, template, context - - if message["type"] == "http.response.start": - assert ( - not response_started - ), 'Received multiple "http.response.start" messages.' - raw_kwargs["version"] = 11 - raw_kwargs["status"] = message["status"] - raw_kwargs["reason"] = _get_reason_phrase(message["status"]) - raw_kwargs["headers"] = [ - (key.decode(), value.decode()) for key, value in message["headers"] - ] - raw_kwargs["preload_content"] = False - raw_kwargs["original_response"] = _MockOriginalResponse( - raw_kwargs["headers"] - ) - response_started = True - elif message["type"] == "http.response.body": - assert ( - response_started - ), 'Received "http.response.body" without "http.response.start".' - assert ( - not response_complete - ), 'Received "http.response.body" after response completed.' - body = message.get("body", b"") - more_body = message.get("more_body", False) - if request.method != "HEAD": - raw_kwargs["body"].write(body) - if not more_body: - raw_kwargs["body"].seek(0) - response_complete = True - elif message["type"] == "http.response.template": - template = message["template"] - context = message["context"] - - try: - loop = asyncio.get_event_loop() - except RuntimeError: - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - try: - loop.run_until_complete(self.app(scope, receive, send)) - except BaseException as exc: - if self.raise_server_exceptions: - raise exc from None - - if self.raise_server_exceptions: - assert response_started, "TestClient did not receive any response." - elif not response_started: - raw_kwargs = { - "version": 11, - "status": 500, - "reason": "Internal Server Error", - "headers": [], - "preload_content": False, - "original_response": _MockOriginalResponse([]), - "body": io.BytesIO(), - } - - raw = requests.packages.urllib3.HTTPResponse(**raw_kwargs) - response = self.build_response(request, raw) - if template is not None: - response.template = template - response.context = context - return response - - -class WebSocketTestSession: - def __init__(self, app: ASGI3App, scope: Scope) -> None: - self.app = app - self.scope = scope - self.accepted_subprotocol = None - self._loop = asyncio.new_event_loop() - self._receive_queue = queue.Queue() # type: queue.Queue - self._send_queue = queue.Queue() # type: queue.Queue - self._thread = threading.Thread(target=self._run) - self.send({"type": "websocket.connect"}) - self._thread.start() - message = self.receive() - self._raise_on_close(message) - self.accepted_subprotocol = message.get("subprotocol", None) - - def __enter__(self) -> "WebSocketTestSession": - return self - - def __exit__(self, *args: typing.Any) -> None: - self.close(1000) - self._thread.join() - while not self._send_queue.empty(): - message = self._send_queue.get() - if isinstance(message, BaseException): - raise message - - def _run(self) -> None: - """ - The sub-thread in which the websocket session runs. - """ - scope = self.scope - receive = self._asgi_receive - send = self._asgi_send - try: - self._loop.run_until_complete(self.app(scope, receive, send)) - except BaseException as exc: - self._send_queue.put(exc) - - async def _asgi_receive(self) -> Message: - while self._receive_queue.empty(): - await asyncio.sleep(0) - return self._receive_queue.get() - - async def _asgi_send(self, message: Message) -> None: - self._send_queue.put(message) - - def _raise_on_close(self, message: Message) -> None: - if message["type"] == "websocket.close": - raise WebSocketDisconnect(message.get("code", 1000)) - - def send(self, message: Message) -> None: - self._receive_queue.put(message) - - def send_text(self, data: str) -> None: - self.send({"type": "websocket.receive", "text": data}) - - def send_bytes(self, data: bytes) -> None: - self.send({"type": "websocket.receive", "bytes": data}) - - def send_json(self, data: typing.Any, mode: str = "text") -> None: - assert mode in ["text", "binary"] - text = json.dumps(data) - if mode == "text": - self.send({"type": "websocket.receive", "text": text}) - else: - self.send({"type": "websocket.receive", "bytes": text.encode("utf-8")}) - - def close(self, code: int = 1000) -> None: - self.send({"type": "websocket.disconnect", "code": code}) - - def receive(self) -> Message: - message = self._send_queue.get() - if isinstance(message, BaseException): - raise message - return message - - def receive_text(self) -> str: - message = self.receive() - self._raise_on_close(message) - return message["text"] - - def receive_bytes(self) -> bytes: - message = self.receive() - self._raise_on_close(message) - return message["bytes"] - - def receive_json(self, mode: str = "text") -> typing.Any: - assert mode in ["text", "binary"] - message = self.receive() - self._raise_on_close(message) - if mode == "text": - text = message["text"] - else: - text = message["bytes"].decode("utf-8") - return json.loads(text) - - -class TestClient(requests.Session): - __test__ = False # For pytest to not discover this up. - - def __init__( - self, - app: typing.Union[ASGI2App, ASGI3App], - base_url: str = "http://testserver", - raise_server_exceptions: bool = True, - root_path: str = "", - ) -> None: - super(TestClient, self).__init__() - if _is_asgi3(app): - app = typing.cast(ASGI3App, app) - asgi_app = app - else: - app = typing.cast(ASGI2App, app) - asgi_app = _WrapASGI2(app) #  type: ignore - adapter = _ASGIAdapter( - asgi_app, - raise_server_exceptions=raise_server_exceptions, - root_path=root_path, - ) - self.mount("http://", adapter) - self.mount("https://", adapter) - self.mount("ws://", adapter) - self.mount("wss://", adapter) - self.headers.update({"user-agent": "testclient"}) - self.app = asgi_app - self.base_url = base_url - - def request( # type: ignore - self, - method: str, - url: str, - params: Params = None, - data: DataType = None, - headers: typing.MutableMapping[str, str] = None, - cookies: Cookies = None, - files: FileType = None, - auth: AuthType = None, - timeout: TimeOut = None, - allow_redirects: bool = None, - proxies: typing.MutableMapping[str, str] = None, - hooks: typing.Any = None, - stream: bool = None, - verify: typing.Union[bool, str] = None, - cert: typing.Union[str, typing.Tuple[str, str]] = None, - json: typing.Any = None, - ) -> requests.Response: - url = urljoin(self.base_url, url) - return super().request( - method, - url, - params=params, - data=data, - headers=headers, - cookies=cookies, - files=files, - auth=auth, - timeout=timeout, - allow_redirects=allow_redirects, - proxies=proxies, - hooks=hooks, - stream=stream, - verify=verify, - cert=cert, - json=json, - ) - - def websocket_connect( - self, url: str, subprotocols: typing.Sequence[str] = None, **kwargs: typing.Any - ) -> typing.Any: - url = urljoin("ws://testserver", url) - headers = kwargs.get("headers", {}) - headers.setdefault("connection", "upgrade") - headers.setdefault("sec-websocket-key", "testserver==") - headers.setdefault("sec-websocket-version", "13") - if subprotocols is not None: - headers.setdefault("sec-websocket-protocol", ", ".join(subprotocols)) - kwargs["headers"] = headers - try: - super().request("GET", url, **kwargs) - except _Upgrade as exc: - session = exc.session - else: - raise RuntimeError("Expected WebSocket upgrade") # pragma: no cover - - return session - - def __enter__(self) -> requests.Session: - loop = asyncio.get_event_loop() - self.send_queue = asyncio.Queue() # type: asyncio.Queue - self.receive_queue = asyncio.Queue() # type: asyncio.Queue - self.task = loop.create_task(self.lifespan()) - loop.run_until_complete(self.wait_startup()) - return self - - def __exit__(self, *args: typing.Any) -> None: - loop = asyncio.get_event_loop() - loop.run_until_complete(self.wait_shutdown()) - - async def lifespan(self) -> None: - scope = {"type": "lifespan"} - try: - await self.app(scope, self.receive_queue.get, self.send_queue.put) - finally: - await self.send_queue.put(None) - - async def wait_startup(self) -> None: - await self.receive_queue.put({"type": "lifespan.startup"}) - message = await self.send_queue.get() - if message is None: - self.task.result() - assert message["type"] in ( - "lifespan.startup.complete", - "lifespan.startup.failed", - ) - if message["type"] == "lifespan.startup.failed": - message = await self.send_queue.get() - if message is None: - self.task.result() - - async def wait_shutdown(self) -> None: - await self.receive_queue.put({"type": "lifespan.shutdown"}) - message = await self.send_queue.get() - if message is None: - self.task.result() - assert message["type"] == "lifespan.shutdown.complete" - await self.task diff --git a/env/lib/python3.8/site-packages/starlette/types.py b/env/lib/python3.8/site-packages/starlette/types.py deleted file mode 100644 index 888645ca..00000000 --- a/env/lib/python3.8/site-packages/starlette/types.py +++ /dev/null @@ -1,9 +0,0 @@ -import typing - -Scope = typing.MutableMapping[str, typing.Any] -Message = typing.MutableMapping[str, typing.Any] - -Receive = typing.Callable[[], typing.Awaitable[Message]] -Send = typing.Callable[[Message], typing.Awaitable[None]] - -ASGIApp = typing.Callable[[Scope, Receive, Send], typing.Awaitable[None]] diff --git a/env/lib/python3.8/site-packages/starlette/websockets.py b/env/lib/python3.8/site-packages/starlette/websockets.py deleted file mode 100644 index b9b8844d..00000000 --- a/env/lib/python3.8/site-packages/starlette/websockets.py +++ /dev/null @@ -1,150 +0,0 @@ -import enum -import json -import typing - -from starlette.requests import HTTPConnection -from starlette.types import Message, Receive, Scope, Send - - -class WebSocketState(enum.Enum): - CONNECTING = 0 - CONNECTED = 1 - DISCONNECTED = 2 - - -class WebSocketDisconnect(Exception): - def __init__(self, code: int = 1000) -> None: - self.code = code - - -class WebSocket(HTTPConnection): - def __init__(self, scope: Scope, receive: Receive, send: Send) -> None: - super().__init__(scope) - assert scope["type"] == "websocket" - self._receive = receive - self._send = send - self.client_state = WebSocketState.CONNECTING - self.application_state = WebSocketState.CONNECTING - - async def receive(self) -> Message: - """ - Receive ASGI websocket messages, ensuring valid state transitions. - """ - if self.client_state == WebSocketState.CONNECTING: - message = await self._receive() - message_type = message["type"] - assert message_type == "websocket.connect" - self.client_state = WebSocketState.CONNECTED - return message - elif self.client_state == WebSocketState.CONNECTED: - message = await self._receive() - message_type = message["type"] - assert message_type in {"websocket.receive", "websocket.disconnect"} - if message_type == "websocket.disconnect": - self.client_state = WebSocketState.DISCONNECTED - return message - else: - raise RuntimeError( - 'Cannot call "receive" once a disconnect message has been received.' - ) - - async def send(self, message: Message) -> None: - """ - Send ASGI websocket messages, ensuring valid state transitions. - """ - if self.application_state == WebSocketState.CONNECTING: - message_type = message["type"] - assert message_type in {"websocket.accept", "websocket.close"} - if message_type == "websocket.close": - self.application_state = WebSocketState.DISCONNECTED - else: - self.application_state = WebSocketState.CONNECTED - await self._send(message) - elif self.application_state == WebSocketState.CONNECTED: - message_type = message["type"] - assert message_type in {"websocket.send", "websocket.close"} - if message_type == "websocket.close": - self.application_state = WebSocketState.DISCONNECTED - await self._send(message) - else: - raise RuntimeError('Cannot call "send" once a close message has been sent.') - - async def accept(self, subprotocol: str = None) -> None: - if self.client_state == WebSocketState.CONNECTING: - # If we haven't yet seen the 'connect' message, then wait for it first. - await self.receive() - await self.send({"type": "websocket.accept", "subprotocol": subprotocol}) - - def _raise_on_disconnect(self, message: Message) -> None: - if message["type"] == "websocket.disconnect": - raise WebSocketDisconnect(message["code"]) - - async def receive_text(self) -> str: - assert self.application_state == WebSocketState.CONNECTED - message = await self.receive() - self._raise_on_disconnect(message) - return message["text"] - - async def receive_bytes(self) -> bytes: - assert self.application_state == WebSocketState.CONNECTED - message = await self.receive() - self._raise_on_disconnect(message) - return message["bytes"] - - async def receive_json(self, mode: str = "text") -> typing.Any: - assert mode in ["text", "binary"] - assert self.application_state == WebSocketState.CONNECTED - message = await self.receive() - self._raise_on_disconnect(message) - - if mode == "text": - text = message["text"] - else: - text = message["bytes"].decode("utf-8") - return json.loads(text) - - async def iter_text(self) -> typing.AsyncIterator[str]: - try: - while True: - yield await self.receive_text() - except WebSocketDisconnect: - pass - - async def iter_bytes(self) -> typing.AsyncIterator[bytes]: - try: - while True: - yield await self.receive_bytes() - except WebSocketDisconnect: - pass - - async def iter_json(self) -> typing.AsyncIterator[typing.Any]: - try: - while True: - yield await self.receive_json() - except WebSocketDisconnect: - pass - - async def send_text(self, data: str) -> None: - await self.send({"type": "websocket.send", "text": data}) - - async def send_bytes(self, data: bytes) -> None: - await self.send({"type": "websocket.send", "bytes": data}) - - async def send_json(self, data: typing.Any, mode: str = "text") -> None: - assert mode in ["text", "binary"] - text = json.dumps(data) - if mode == "text": - await self.send({"type": "websocket.send", "text": text}) - else: - await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")}) - - async def close(self, code: int = 1000) -> None: - await self.send({"type": "websocket.close", "code": code}) - - -class WebSocketClose: - def __init__(self, code: int = 1000) -> None: - self.code = code - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - await send({"type": "websocket.close", "code": self.code}) diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/INSTALLER b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/LICENSE b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/LICENSE deleted file mode 100644 index 5010e307..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -The MIT License - -Copyright 2013-2019 William Pearson -Copyright 2015-2016 Julien Enselme -Copyright 2016 Google Inc. -Copyright 2017 Samuel Vasko -Copyright 2017 Nate Prewitt -Copyright 2017 Jack Evans -Copyright 2019 Filippo Broggini - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/METADATA b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/METADATA deleted file mode 100644 index 6f2635ce..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/METADATA +++ /dev/null @@ -1,255 +0,0 @@ -Metadata-Version: 2.1 -Name: toml -Version: 0.10.2 -Summary: Python Library for Tom's Obvious, Minimal Language -Home-page: https://github.com/uiri/toml -Author: William Pearson -Author-email: uiri@xqz.ca -License: MIT -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.* - -**** -TOML -**** - -.. image:: https://img.shields.io/pypi/v/toml - :target: https://pypi.org/project/toml/ - -.. image:: https://travis-ci.org/uiri/toml.svg?branch=master - :target: https://travis-ci.org/uiri/toml - -.. image:: https://img.shields.io/pypi/pyversions/toml.svg - :target: https://pypi.org/project/toml/ - - -A Python library for parsing and creating `TOML `_. - -The module passes `the TOML test suite `_. - -See also: - -* `The TOML Standard `_ -* `The currently supported TOML specification `_ - -Installation -============ - -To install the latest release on `PyPI `_, -simply run: - -:: - - pip install toml - -Or to install the latest development version, run: - -:: - - git clone https://github.com/uiri/toml.git - cd toml - python setup.py install - -Quick Tutorial -============== - -*toml.loads* takes in a string containing standard TOML-formatted data and -returns a dictionary containing the parsed data. - -.. code:: pycon - - >>> import toml - >>> toml_string = """ - ... # This is a TOML document. - ... - ... title = "TOML Example" - ... - ... [owner] - ... name = "Tom Preston-Werner" - ... dob = 1979-05-27T07:32:00-08:00 # First class dates - ... - ... [database] - ... server = "192.168.1.1" - ... ports = [ 8001, 8001, 8002 ] - ... connection_max = 5000 - ... enabled = true - ... - ... [servers] - ... - ... # Indentation (tabs and/or spaces) is allowed but not required - ... [servers.alpha] - ... ip = "10.0.0.1" - ... dc = "eqdc10" - ... - ... [servers.beta] - ... ip = "10.0.0.2" - ... dc = "eqdc10" - ... - ... [clients] - ... data = [ ["gamma", "delta"], [1, 2] ] - ... - ... # Line breaks are OK when inside arrays - ... hosts = [ - ... "alpha", - ... "omega" - ... ] - ... """ - >>> parsed_toml = toml.loads(toml_string) - - -*toml.dumps* takes a dictionary and returns a string containing the -corresponding TOML-formatted data. - -.. code:: pycon - - >>> new_toml_string = toml.dumps(parsed_toml) - >>> print(new_toml_string) - title = "TOML Example" - [owner] - name = "Tom Preston-Werner" - dob = 1979-05-27T07:32:00Z - [database] - server = "192.168.1.1" - ports = [ 8001, 8001, 8002,] - connection_max = 5000 - enabled = true - [clients] - data = [ [ "gamma", "delta",], [ 1, 2,],] - hosts = [ "alpha", "omega",] - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -*toml.dump* takes a dictionary and a file descriptor and returns a string containing the -corresponding TOML-formatted data. - -.. code:: pycon - - >>> with open('new_toml_file.toml', 'w') as f: - ... new_toml_string = toml.dump(parsed_toml, f) - >>> print(new_toml_string) - title = "TOML Example" - [owner] - name = "Tom Preston-Werner" - dob = 1979-05-27T07:32:00Z - [database] - server = "192.168.1.1" - ports = [ 8001, 8001, 8002,] - connection_max = 5000 - enabled = true - [clients] - data = [ [ "gamma", "delta",], [ 1, 2,],] - hosts = [ "alpha", "omega",] - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -For more functions, view the API Reference below. - -Note ----- - -For Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data. - -.. code:: pycon - - >>> import toml - >>> import numpy as np - >>> a = np.arange(0, 10, dtype=np.double) - >>> output = {'a': a} - >>> toml.dumps(output) - 'a = [ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0",]\n' - >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder()) - 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\n' - -API Reference -============= - -``toml.load(f, _dict=dict)`` - Parse a file or a list of files as TOML and return a dictionary. - - :Args: - * ``f``: A path to a file, list of filepaths (to be read into single - object) or a file descriptor - * ``_dict``: The class of the dictionary object to be returned - - :Returns: - A dictionary (or object ``_dict``) containing parsed TOML data - - :Raises: - * ``TypeError``: When ``f`` is an invalid type or is a list containing - invalid types - * ``TomlDecodeError``: When an error occurs while decoding the file(s) - -``toml.loads(s, _dict=dict)`` - Parse a TOML-formatted string to a dictionary. - - :Args: - * ``s``: The TOML-formatted string to be parsed - * ``_dict``: Specifies the class of the returned toml dictionary - - :Returns: - A dictionary (or object ``_dict``) containing parsed TOML data - - :Raises: - * ``TypeError``: When a non-string object is passed - * ``TomlDecodeError``: When an error occurs while decoding the - TOML-formatted string - -``toml.dump(o, f, encoder=None)`` - Write a dictionary to a file containing TOML-formatted data - - :Args: - * ``o``: An object to be converted into TOML - * ``f``: A File descriptor where the TOML-formatted output should be stored - * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` - - :Returns: - A string containing the TOML-formatted data corresponding to object ``o`` - - :Raises: - * ``TypeError``: When anything other than file descriptor is passed - -``toml.dumps(o, encoder=None)`` - Create a TOML-formatted string from an input object - - :Args: - * ``o``: An object to be converted into TOML - * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` - - :Returns: - A string containing the TOML-formatted data corresponding to object ``o`` - - - -Licensing -========= - -This project is released under the terms of the MIT Open Source License. View -*LICENSE.txt* for more information. - - diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/RECORD b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/RECORD deleted file mode 100644 index 37ad9318..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/RECORD +++ /dev/null @@ -1,16 +0,0 @@ -toml-0.10.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -toml-0.10.2.dist-info/LICENSE,sha256=LZKUgj32yJNXyL5JJ_znk2HWVh5e51MtWSbmOTmqpTY,1252 -toml-0.10.2.dist-info/METADATA,sha256=n_YkspvEihd_QXLIZZ50WVSFz3rZ_k7jQP-OU1WUpWY,7142 -toml-0.10.2.dist-info/RECORD,, -toml-0.10.2.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 -toml-0.10.2.dist-info/top_level.txt,sha256=2BO8ZRNnvJWgXyiQv66LBb_v87qBzcoUtEBefA75Ouk,5 -toml/__init__.py,sha256=Au3kqCwKD0cjbf4yJGOpUFwpsY0WHsC1ZRGvWgIKmpc,723 -toml/__pycache__/__init__.cpython-38.pyc,, -toml/__pycache__/decoder.cpython-38.pyc,, -toml/__pycache__/encoder.cpython-38.pyc,, -toml/__pycache__/ordered.cpython-38.pyc,, -toml/__pycache__/tz.cpython-38.pyc,, -toml/decoder.py,sha256=hSGTLf-2WBDZ_ddoCHWFy6N647XyMSh1o3rN2o4dEFg,38942 -toml/encoder.py,sha256=XjBc8ayvvlsLyd_qDA4tMWDNmMFRS4DpwtuDSWBq7zo,9940 -toml/ordered.py,sha256=mz03lZmV0bmc9lsYRIUOuj7Dsu5Ptwq-UtGVq5FdVZ4,354 -toml/tz.py,sha256=-5vg8wkg_atnVi2TnEveexIVE7T_FxBVr_-2WVfO1oA,701 diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/WHEEL b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/WHEEL deleted file mode 100644 index 6d38aa06..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/top_level.txt b/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/top_level.txt deleted file mode 100644 index bd79a658..00000000 --- a/env/lib/python3.8/site-packages/toml-0.10.2.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -toml diff --git a/env/lib/python3.8/site-packages/toml/__init__.py b/env/lib/python3.8/site-packages/toml/__init__.py deleted file mode 100644 index 7719ac23..00000000 --- a/env/lib/python3.8/site-packages/toml/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Python module which parses and emits TOML. - -Released under the MIT license. -""" - -from toml import encoder -from toml import decoder - -__version__ = "0.10.2" -_spec_ = "0.5.0" - -load = decoder.load -loads = decoder.loads -TomlDecoder = decoder.TomlDecoder -TomlDecodeError = decoder.TomlDecodeError -TomlPreserveCommentDecoder = decoder.TomlPreserveCommentDecoder - -dump = encoder.dump -dumps = encoder.dumps -TomlEncoder = encoder.TomlEncoder -TomlArraySeparatorEncoder = encoder.TomlArraySeparatorEncoder -TomlPreserveInlineDictEncoder = encoder.TomlPreserveInlineDictEncoder -TomlNumpyEncoder = encoder.TomlNumpyEncoder -TomlPreserveCommentEncoder = encoder.TomlPreserveCommentEncoder -TomlPathlibEncoder = encoder.TomlPathlibEncoder diff --git a/env/lib/python3.8/site-packages/toml/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/toml/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index ab393e9c21edf462a1f7c4dc0bccf7d224618550..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 718 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 diff --git a/env/lib/python3.8/site-packages/toml/__pycache__/encoder.cpython-38.pyc b/env/lib/python3.8/site-packages/toml/__pycache__/encoder.cpython-38.pyc deleted file mode 100644 index 9c50017ea1bc47f7897ec95dc55f4e1b258e49f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9419 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 diff --git a/env/lib/python3.8/site-packages/toml/__pycache__/ordered.cpython-38.pyc b/env/lib/python3.8/site-packages/toml/__pycache__/ordered.cpython-38.pyc deleted file mode 100644 index c61c9bb66e25c4f3d83b1d45bdbecd14ef8a562d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 911 zcmb_by>1jS5FW3+cbnWD1PX)%FL1@>Xpkrnq6mU26oF#!ZMiT4M4F9DP;k*?xF z_5pYS9>XmauRz6&Z|`&xsSvaBXg+)W%{McNP>AwMvHp9FSIAb5$(zd@%# zGYcil8KXF{Ny&2_V~(-N1%ub1g-&lkr$$`!JViXvL&QVF5f5~B0@J-;$OcmuMsJ-q z&gi2;wFKYQrF~VY8aFra$V8~<#;)-m_{SI+$eD&bS-~mOOeZ&4&Q~BH7nqHQ`^39R z)$?JsTceoxX!(ceTDXEUb_LhTS<-UNzQu}9pi7QXS1L8??LlziT<%B<)fXP%TP>Qud`RYrV7-kEQ&yT-fzVqzsc@v@+JB z+`CA=c6TT`AeW*W;EJiUB;x-zhknfJpXT65mZP?~F}bKYmJo$g&uHtmp7nXRJ#+Vn z;I{G~-~q93$|rn09fpyrtu?AG>dMD42SGz~^z}IUVPc~ky}rY{RTr}7>$$w3(mfS1 JX87=f!5_TMzpwxR diff --git a/env/lib/python3.8/site-packages/toml/__pycache__/tz.cpython-38.pyc b/env/lib/python3.8/site-packages/toml/__pycache__/tz.cpython-38.pyc deleted file mode 100644 index 4c4185c34d59ecbb5d4aaba8eb1330ed8def3847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1271 zcmZuxJ#Q015Z&E7pU+NAj1owKkf5NzLdjWz0uVw-Dd^mg6u4O(o^^c5eVE;KP%L)| zB{eOS`4KeyjBBa<7t+AYo$XjSYu)VL&g{H5Z}xoDXw(^wSKoijUxKke^s+o$e0hhD zd4dKQ@R%jM%M;NRoV{ltz`11LD1PB|9dJLeR%MEjtR-^Kj-#}nQCn%YXmedkP-@uAhUZe=!5vfdnU6OYByRjGL@2f(LYEw{k0)%KdL}x# zb98vn;st@L836(Ie|WsZX_zSDHwSLafJ@H`BuQ34-p2(2T7snu 1 and n[0] == '0' and n[1] != '.': - return False - if '__' in n: - return False - return True - - -def load(f, _dict=dict, decoder=None): - """Parses named file or files as toml and returns a dictionary - - Args: - f: Path to the file to open, array of files to read into single dict - or a file descriptor - _dict: (optional) Specifies the class of the returned toml dictionary - decoder: The decoder to use - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError -- When f is invalid type - TomlDecodeError: Error while decoding toml - IOError / FileNotFoundError -- When an array with no valid (existing) - (Python 2 / Python 3) file paths is passed - """ - - if _ispath(f): - with io.open(_getpath(f), encoding='utf-8') as ffile: - return loads(ffile.read(), _dict, decoder) - elif isinstance(f, list): - from os import path as op - from warnings import warn - if not [path for path in f if op.exists(path)]: - error_msg = "Load expects a list to contain filenames only." - error_msg += linesep - error_msg += ("The list needs to contain the path of at least one " - "existing file.") - raise FNFError(error_msg) - if decoder is None: - decoder = TomlDecoder(_dict) - d = decoder.get_empty_table() - for l in f: # noqa: E741 - if op.exists(l): - d.update(load(l, _dict, decoder)) - else: - warn("Non-existent filename in list with at least one valid " - "filename") - return d - else: - try: - return loads(f.read(), _dict, decoder) - except AttributeError: - raise TypeError("You can only load a file descriptor, filename or " - "list") - - -_groupname_re = re.compile(r'^[A-Za-z0-9_-]+$') - - -def loads(s, _dict=dict, decoder=None): - """Parses string as toml - - Args: - s: String to be parsed - _dict: (optional) Specifies the class of the returned toml dictionary - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError: When a non-string is passed - TomlDecodeError: Error while decoding toml - """ - - implicitgroups = [] - if decoder is None: - decoder = TomlDecoder(_dict) - retval = decoder.get_empty_table() - currentlevel = retval - if not isinstance(s, basestring): - raise TypeError("Expecting something like a string") - - if not isinstance(s, unicode): - s = s.decode('utf8') - - original = s - sl = list(s) - openarr = 0 - openstring = False - openstrchar = "" - multilinestr = False - arrayoftables = False - beginline = True - keygroup = False - dottedkey = False - keyname = 0 - key = '' - prev_key = '' - line_no = 1 - - for i, item in enumerate(sl): - if item == '\r' and sl[i + 1] == '\n': - sl[i] = ' ' - continue - if keyname: - key += item - if item == '\n': - raise TomlDecodeError("Key name found without value." - " Reached end of line.", original, i) - if openstring: - if item == openstrchar: - oddbackslash = False - k = 1 - while i >= k and sl[i - k] == '\\': - oddbackslash = not oddbackslash - k += 1 - if not oddbackslash: - keyname = 2 - openstring = False - openstrchar = "" - continue - elif keyname == 1: - if item.isspace(): - keyname = 2 - continue - elif item == '.': - dottedkey = True - continue - elif item.isalnum() or item == '_' or item == '-': - continue - elif (dottedkey and sl[i - 1] == '.' and - (item == '"' or item == "'")): - openstring = True - openstrchar = item - continue - elif keyname == 2: - if item.isspace(): - if dottedkey: - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != '.': - keyname = 1 - continue - if item == '.': - dottedkey = True - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != '.': - keyname = 1 - continue - if item == '=': - keyname = 0 - prev_key = key[:-1].rstrip() - key = '' - dottedkey = False - else: - raise TomlDecodeError("Found invalid character in key name: '" + - item + "'. Try quoting the key name.", - original, i) - if item == "'" and openstrchar != '"': - k = 1 - try: - while sl[i - k] == "'": - k += 1 - if k == 3: - break - except IndexError: - pass - if k == 3: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = "'" - else: - openstrchar = "" - if item == '"' and openstrchar != "'": - oddbackslash = False - k = 1 - tripquote = False - try: - while sl[i - k] == '"': - k += 1 - if k == 3: - tripquote = True - break - if k == 1 or (k == 3 and tripquote): - while sl[i - k] == '\\': - oddbackslash = not oddbackslash - k += 1 - except IndexError: - pass - if not oddbackslash: - if tripquote: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = '"' - else: - openstrchar = "" - if item == '#' and (not openstring and not keygroup and - not arrayoftables): - j = i - comment = "" - try: - while sl[j] != '\n': - comment += s[j] - sl[j] = ' ' - j += 1 - except IndexError: - break - if not openarr: - decoder.preserve_comment(line_no, prev_key, comment, beginline) - if item == '[' and (not openstring and not keygroup and - not arrayoftables): - if beginline: - if len(sl) > i + 1 and sl[i + 1] == '[': - arrayoftables = True - else: - keygroup = True - else: - openarr += 1 - if item == ']' and not openstring: - if keygroup: - keygroup = False - elif arrayoftables: - if sl[i - 1] == ']': - arrayoftables = False - else: - openarr -= 1 - if item == '\n': - if openstring or multilinestr: - if not multilinestr: - raise TomlDecodeError("Unbalanced quotes", original, i) - if ((sl[i - 1] == "'" or sl[i - 1] == '"') and ( - sl[i - 2] == sl[i - 1])): - sl[i] = sl[i - 1] - if sl[i - 3] == sl[i - 1]: - sl[i - 3] = ' ' - elif openarr: - sl[i] = ' ' - else: - beginline = True - line_no += 1 - elif beginline and sl[i] != ' ' and sl[i] != '\t': - beginline = False - if not keygroup and not arrayoftables: - if sl[i] == '=': - raise TomlDecodeError("Found empty keyname. ", original, i) - keyname = 1 - key += item - if keyname: - raise TomlDecodeError("Key name found without value." - " Reached end of file.", original, len(s)) - if openstring: # reached EOF and have an unterminated string - raise TomlDecodeError("Unterminated string found." - " Reached end of file.", original, len(s)) - s = ''.join(sl) - s = s.split('\n') - multikey = None - multilinestr = "" - multibackslash = False - pos = 0 - for idx, line in enumerate(s): - if idx > 0: - pos += len(s[idx - 1]) + 1 - - decoder.embed_comments(idx, currentlevel) - - if not multilinestr or multibackslash or '\n' not in multilinestr: - line = line.strip() - if line == "" and (not multikey or multibackslash): - continue - if multikey: - if multibackslash: - multilinestr += line - else: - multilinestr += line - multibackslash = False - closed = False - if multilinestr[0] == '[': - closed = line[-1] == ']' - elif len(line) > 2: - closed = (line[-1] == multilinestr[0] and - line[-2] == multilinestr[0] and - line[-3] == multilinestr[0]) - if closed: - try: - value, vtype = decoder.load_value(multilinestr) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - currentlevel[multikey] = value - multikey = None - multilinestr = "" - else: - k = len(multilinestr) - 1 - while k > -1 and multilinestr[k] == '\\': - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = multilinestr[:-1] - else: - multilinestr += "\n" - continue - if line[0] == '[': - arrayoftables = False - if len(line) == 1: - raise TomlDecodeError("Opening key group bracket on line by " - "itself.", original, pos) - if line[1] == '[': - arrayoftables = True - line = line[2:] - splitstr = ']]' - else: - line = line[1:] - splitstr = ']' - i = 1 - quotesplits = decoder._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and splitstr in quotesplit: - break - i += quotesplit.count(splitstr) - quoted = not quoted - line = line.split(splitstr, i) - if len(line) < i + 1 or line[-1].strip() != "": - raise TomlDecodeError("Key group not on a line by itself.", - original, pos) - groups = splitstr.join(line[:-1]).split('.') - i = 0 - while i < len(groups): - groups[i] = groups[i].strip() - if len(groups[i]) > 0 and (groups[i][0] == '"' or - groups[i][0] == "'"): - groupstr = groups[i] - j = i + 1 - while ((not groupstr[0] == groupstr[-1]) or - len(groupstr) == 1): - j += 1 - if j > len(groups) + 2: - raise TomlDecodeError("Invalid group name '" + - groupstr + "' Something " + - "went wrong.", original, pos) - groupstr = '.'.join(groups[i:j]).strip() - groups[i] = groupstr[1:-1] - groups[i + 1:j] = [] - else: - if not _groupname_re.match(groups[i]): - raise TomlDecodeError("Invalid group name '" + - groups[i] + "'. Try quoting it.", - original, pos) - i += 1 - currentlevel = retval - for i in _range(len(groups)): - group = groups[i] - if group == "": - raise TomlDecodeError("Can't have a keygroup with an empty " - "name", original, pos) - try: - currentlevel[group] - if i == len(groups) - 1: - if group in implicitgroups: - implicitgroups.remove(group) - if arrayoftables: - raise TomlDecodeError("An implicitly defined " - "table can't be an array", - original, pos) - elif arrayoftables: - currentlevel[group].append(decoder.get_empty_table() - ) - else: - raise TomlDecodeError("What? " + group + - " already exists?" + - str(currentlevel), - original, pos) - except TypeError: - currentlevel = currentlevel[-1] - if group not in currentlevel: - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - except KeyError: - if i != len(groups) - 1: - implicitgroups.append(group) - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - currentlevel = currentlevel[group] - if arrayoftables: - try: - currentlevel = currentlevel[-1] - except KeyError: - pass - elif line[0] == "{": - if line[-1] != "}": - raise TomlDecodeError("Line breaks are not allowed in inline" - "objects", original, pos) - try: - decoder.load_inline_object(line, currentlevel, multikey, - multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - elif "=" in line: - try: - ret = decoder.load_line(line, currentlevel, multikey, - multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - if ret is not None: - multikey, multilinestr, multibackslash = ret - return retval - - -def _load_date(val): - microsecond = 0 - tz = None - try: - if len(val) > 19: - if val[19] == '.': - if val[-1].upper() == 'Z': - subsecondval = val[20:-1] - tzval = "Z" - else: - subsecondvalandtz = val[20:] - if '+' in subsecondvalandtz: - splitpoint = subsecondvalandtz.index('+') - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - elif '-' in subsecondvalandtz: - splitpoint = subsecondvalandtz.index('-') - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - else: - tzval = None - subsecondval = subsecondvalandtz - if tzval is not None: - tz = TomlTz(tzval) - microsecond = int(int(subsecondval) * - (10 ** (6 - len(subsecondval)))) - else: - tz = TomlTz(val[19:]) - except ValueError: - tz = None - if "-" not in val[1:]: - return None - try: - if len(val) == 10: - d = datetime.date( - int(val[:4]), int(val[5:7]), - int(val[8:10])) - else: - d = datetime.datetime( - int(val[:4]), int(val[5:7]), - int(val[8:10]), int(val[11:13]), - int(val[14:16]), int(val[17:19]), microsecond, tz) - except ValueError: - return None - return d - - -def _load_unicode_escapes(v, hexbytes, prefix): - skip = False - i = len(v) - 1 - while i > -1 and v[i] == '\\': - skip = not skip - i -= 1 - for hx in hexbytes: - if skip: - skip = False - i = len(hx) - 1 - while i > -1 and hx[i] == '\\': - skip = not skip - i -= 1 - v += prefix - v += hx - continue - hxb = "" - i = 0 - hxblen = 4 - if prefix == "\\U": - hxblen = 8 - hxb = ''.join(hx[i:i + hxblen]).lower() - if hxb.strip('0123456789abcdef'): - raise ValueError("Invalid escape sequence: " + hxb) - if hxb[0] == "d" and hxb[1].strip('01234567'): - raise ValueError("Invalid escape sequence: " + hxb + - ". Only scalar unicode points are allowed.") - v += unichr(int(hxb, 16)) - v += unicode(hx[len(hxb):]) - return v - - -# Unescape TOML string values. - -# content after the \ -_escapes = ['0', 'b', 'f', 'n', 'r', 't', '"'] -# What it should be replaced by -_escapedchars = ['\0', '\b', '\f', '\n', '\r', '\t', '\"'] -# Used for substitution -_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) - - -def _unescape(v): - """Unescape characters in a TOML string.""" - i = 0 - backslash = False - while i < len(v): - if backslash: - backslash = False - if v[i] in _escapes: - v = v[:i - 1] + _escape_to_escapedchars[v[i]] + v[i + 1:] - elif v[i] == '\\': - v = v[:i - 1] + v[i:] - elif v[i] == 'u' or v[i] == 'U': - i += 1 - else: - raise ValueError("Reserved escape sequence used") - continue - elif v[i] == '\\': - backslash = True - i += 1 - return v - - -class InlineTableDict(object): - """Sentinel subclass of dict for inline tables.""" - - -class TomlDecoder(object): - - def __init__(self, _dict=dict): - self._dict = _dict - - def get_empty_table(self): - return self._dict() - - def get_empty_inline_table(self): - class DynamicInlineTableDict(self._dict, InlineTableDict): - """Concrete sentinel subclass for inline tables. - It is a subclass of _dict which is passed in dynamically at load - time - - It is also a subclass of InlineTableDict - """ - - return DynamicInlineTableDict() - - def load_inline_object(self, line, currentlevel, multikey=False, - multibackslash=False): - candidate_groups = line[1:-1].split(",") - groups = [] - if len(candidate_groups) == 1 and not candidate_groups[0].strip(): - candidate_groups.pop() - while len(candidate_groups) > 0: - candidate_group = candidate_groups.pop(0) - try: - _, value = candidate_group.split('=', 1) - except ValueError: - raise ValueError("Invalid inline table encountered") - value = value.strip() - if ((value[0] == value[-1] and value[0] in ('"', "'")) or ( - value[0] in '-0123456789' or - value in ('true', 'false') or - (value[0] == "[" and value[-1] == "]") or - (value[0] == '{' and value[-1] == '}'))): - groups.append(candidate_group) - elif len(candidate_groups) > 0: - candidate_groups[0] = (candidate_group + "," + - candidate_groups[0]) - else: - raise ValueError("Invalid inline table value encountered") - for group in groups: - status = self.load_line(group, currentlevel, multikey, - multibackslash) - if status is not None: - break - - def _get_split_on_quotes(self, line): - doublequotesplits = line.split('"') - quoted = False - quotesplits = [] - if len(doublequotesplits) > 1 and "'" in doublequotesplits[0]: - singlequotesplits = doublequotesplits[0].split("'") - doublequotesplits = doublequotesplits[1:] - while len(singlequotesplits) % 2 == 0 and len(doublequotesplits): - singlequotesplits[-1] += '"' + doublequotesplits[0] - doublequotesplits = doublequotesplits[1:] - if "'" in singlequotesplits[-1]: - singlequotesplits = (singlequotesplits[:-1] + - singlequotesplits[-1].split("'")) - quotesplits += singlequotesplits - for doublequotesplit in doublequotesplits: - if quoted: - quotesplits.append(doublequotesplit) - else: - quotesplits += doublequotesplit.split("'") - quoted = not quoted - return quotesplits - - def load_line(self, line, currentlevel, multikey, multibackslash): - i = 1 - quotesplits = self._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and '=' in quotesplit: - break - i += quotesplit.count('=') - quoted = not quoted - pair = line.split('=', i) - strictly_valid = _strictly_valid_num(pair[-1]) - if _number_with_underscores.match(pair[-1]): - pair[-1] = pair[-1].replace('_', '') - while len(pair[-1]) and (pair[-1][0] != ' ' and pair[-1][0] != '\t' and - pair[-1][0] != "'" and pair[-1][0] != '"' and - pair[-1][0] != '[' and pair[-1][0] != '{' and - pair[-1].strip() != 'true' and - pair[-1].strip() != 'false'): - try: - float(pair[-1]) - break - except ValueError: - pass - if _load_date(pair[-1]) is not None: - break - if TIME_RE.match(pair[-1]): - break - i += 1 - prev_val = pair[-1] - pair = line.split('=', i) - if prev_val == pair[-1]: - raise ValueError("Invalid date or number") - if strictly_valid: - strictly_valid = _strictly_valid_num(pair[-1]) - pair = ['='.join(pair[:-1]).strip(), pair[-1].strip()] - if '.' in pair[0]: - if '"' in pair[0] or "'" in pair[0]: - quotesplits = self._get_split_on_quotes(pair[0]) - quoted = False - levels = [] - for quotesplit in quotesplits: - if quoted: - levels.append(quotesplit) - else: - levels += [level.strip() for level in - quotesplit.split('.')] - quoted = not quoted - else: - levels = pair[0].split('.') - while levels[-1] == "": - levels = levels[:-1] - for level in levels[:-1]: - if level == "": - continue - if level not in currentlevel: - currentlevel[level] = self.get_empty_table() - currentlevel = currentlevel[level] - pair[0] = levels[-1].strip() - elif (pair[0][0] == '"' or pair[0][0] == "'") and \ - (pair[0][-1] == pair[0][0]): - pair[0] = _unescape(pair[0][1:-1]) - k, koffset = self._load_line_multiline_str(pair[1]) - if k > -1: - while k > -1 and pair[1][k + koffset] == '\\': - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = pair[1][:-1] - else: - multilinestr = pair[1] + "\n" - multikey = pair[0] - else: - value, vtype = self.load_value(pair[1], strictly_valid) - try: - currentlevel[pair[0]] - raise ValueError("Duplicate keys!") - except TypeError: - raise ValueError("Duplicate keys!") - except KeyError: - if multikey: - return multikey, multilinestr, multibackslash - else: - currentlevel[pair[0]] = value - - def _load_line_multiline_str(self, p): - poffset = 0 - if len(p) < 3: - return -1, poffset - if p[0] == '[' and (p.strip()[-1] != ']' and - self._load_array_isstrarray(p)): - newp = p[1:].strip().split(',') - while len(newp) > 1 and newp[-1][0] != '"' and newp[-1][0] != "'": - newp = newp[:-2] + [newp[-2] + ',' + newp[-1]] - newp = newp[-1] - poffset = len(p) - len(newp) - p = newp - if p[0] != '"' and p[0] != "'": - return -1, poffset - if p[1] != p[0] or p[2] != p[0]: - return -1, poffset - if len(p) > 5 and p[-1] == p[0] and p[-2] == p[0] and p[-3] == p[0]: - return -1, poffset - return len(p) - 1, poffset - - def load_value(self, v, strictly_valid=True): - if not v: - raise ValueError("Empty value is invalid") - if v == 'true': - return (True, "bool") - elif v.lower() == 'true': - raise ValueError("Only all lowercase booleans allowed") - elif v == 'false': - return (False, "bool") - elif v.lower() == 'false': - raise ValueError("Only all lowercase booleans allowed") - elif v[0] == '"' or v[0] == "'": - quotechar = v[0] - testv = v[1:].split(quotechar) - triplequote = False - triplequotecount = 0 - if len(testv) > 1 and testv[0] == '' and testv[1] == '': - testv = testv[2:] - triplequote = True - closed = False - for tv in testv: - if tv == '': - if triplequote: - triplequotecount += 1 - else: - closed = True - else: - oddbackslash = False - try: - i = -1 - j = tv[i] - while j == '\\': - oddbackslash = not oddbackslash - i -= 1 - j = tv[i] - except IndexError: - pass - if not oddbackslash: - if closed: - raise ValueError("Found tokens after a closed " + - "string. Invalid TOML.") - else: - if not triplequote or triplequotecount > 1: - closed = True - else: - triplequotecount = 0 - if quotechar == '"': - escapeseqs = v.split('\\')[1:] - backslash = False - for i in escapeseqs: - if i == '': - backslash = not backslash - else: - if i[0] not in _escapes and (i[0] != 'u' and - i[0] != 'U' and - not backslash): - raise ValueError("Reserved escape sequence used") - if backslash: - backslash = False - for prefix in ["\\u", "\\U"]: - if prefix in v: - hexbytes = v.split(prefix) - v = _load_unicode_escapes(hexbytes[0], hexbytes[1:], - prefix) - v = _unescape(v) - if len(v) > 1 and v[1] == quotechar and (len(v) < 3 or - v[1] == v[2]): - v = v[2:-2] - return (v[1:-1], "str") - elif v[0] == '[': - return (self.load_array(v), "array") - elif v[0] == '{': - inline_object = self.get_empty_inline_table() - self.load_inline_object(v, inline_object) - return (inline_object, "inline_object") - elif TIME_RE.match(v): - h, m, s, _, ms = TIME_RE.match(v).groups() - time = datetime.time(int(h), int(m), int(s), int(ms) if ms else 0) - return (time, "time") - else: - parsed_date = _load_date(v) - if parsed_date is not None: - return (parsed_date, "date") - if not strictly_valid: - raise ValueError("Weirdness with leading zeroes or " - "underscores in your number.") - itype = "int" - neg = False - if v[0] == '-': - neg = True - v = v[1:] - elif v[0] == '+': - v = v[1:] - v = v.replace('_', '') - lowerv = v.lower() - if '.' in v or ('x' not in v and ('e' in v or 'E' in v)): - if '.' in v and v.split('.', 1)[1] == '': - raise ValueError("This float is missing digits after " - "the point") - if v[0] not in '0123456789': - raise ValueError("This float doesn't have a leading " - "digit") - v = float(v) - itype = "float" - elif len(lowerv) == 3 and (lowerv == 'inf' or lowerv == 'nan'): - v = float(v) - itype = "float" - if itype == "int": - v = int(v, 0) - if neg: - return (0 - v, itype) - return (v, itype) - - def bounded_string(self, s): - if len(s) == 0: - return True - if s[-1] != s[0]: - return False - i = -2 - backslash = False - while len(s) + i > 0: - if s[i] == "\\": - backslash = not backslash - i -= 1 - else: - break - return not backslash - - def _load_array_isstrarray(self, a): - a = a[1:-1].strip() - if a != '' and (a[0] == '"' or a[0] == "'"): - return True - return False - - def load_array(self, a): - atype = None - retval = [] - a = a.strip() - if '[' not in a[1:-1] or "" != a[1:-1].split('[')[0].strip(): - strarray = self._load_array_isstrarray(a) - if not a[1:-1].strip().startswith('{'): - a = a[1:-1].split(',') - else: - # a is an inline object, we must find the matching parenthesis - # to define groups - new_a = [] - start_group_index = 1 - end_group_index = 2 - open_bracket_count = 1 if a[start_group_index] == '{' else 0 - in_str = False - while end_group_index < len(a[1:]): - if a[end_group_index] == '"' or a[end_group_index] == "'": - if in_str: - backslash_index = end_group_index - 1 - while (backslash_index > -1 and - a[backslash_index] == '\\'): - in_str = not in_str - backslash_index -= 1 - in_str = not in_str - if not in_str and a[end_group_index] == '{': - open_bracket_count += 1 - if in_str or a[end_group_index] != '}': - end_group_index += 1 - continue - elif a[end_group_index] == '}' and open_bracket_count > 1: - open_bracket_count -= 1 - end_group_index += 1 - continue - - # Increase end_group_index by 1 to get the closing bracket - end_group_index += 1 - - new_a.append(a[start_group_index:end_group_index]) - - # The next start index is at least after the closing - # bracket, a closing bracket can be followed by a comma - # since we are in an array. - start_group_index = end_group_index + 1 - while (start_group_index < len(a[1:]) and - a[start_group_index] != '{'): - start_group_index += 1 - end_group_index = start_group_index + 1 - a = new_a - b = 0 - if strarray: - while b < len(a) - 1: - ab = a[b].strip() - while (not self.bounded_string(ab) or - (len(ab) > 2 and - ab[0] == ab[1] == ab[2] and - ab[-2] != ab[0] and - ab[-3] != ab[0])): - a[b] = a[b] + ',' + a[b + 1] - ab = a[b].strip() - if b < len(a) - 2: - a = a[:b + 1] + a[b + 2:] - else: - a = a[:b + 1] - b += 1 - else: - al = list(a[1:-1]) - a = [] - openarr = 0 - j = 0 - for i in _range(len(al)): - if al[i] == '[': - openarr += 1 - elif al[i] == ']': - openarr -= 1 - elif al[i] == ',' and not openarr: - a.append(''.join(al[j:i])) - j = i + 1 - a.append(''.join(al[j:])) - for i in _range(len(a)): - a[i] = a[i].strip() - if a[i] != '': - nval, ntype = self.load_value(a[i]) - if atype: - if ntype != atype: - raise ValueError("Not a homogeneous array") - else: - atype = ntype - retval.append(nval) - return retval - - def preserve_comment(self, line_no, key, comment, beginline): - pass - - def embed_comments(self, idx, currentlevel): - pass - - -class TomlPreserveCommentDecoder(TomlDecoder): - - def __init__(self, _dict=dict): - self.saved_comments = {} - super(TomlPreserveCommentDecoder, self).__init__(_dict) - - def preserve_comment(self, line_no, key, comment, beginline): - self.saved_comments[line_no] = (key, comment, beginline) - - def embed_comments(self, idx, currentlevel): - if idx not in self.saved_comments: - return - - key, comment, beginline = self.saved_comments[idx] - currentlevel[key] = CommentValue(currentlevel[key], comment, beginline, - self._dict) diff --git a/env/lib/python3.8/site-packages/toml/encoder.py b/env/lib/python3.8/site-packages/toml/encoder.py deleted file mode 100644 index bf17a72b..00000000 --- a/env/lib/python3.8/site-packages/toml/encoder.py +++ /dev/null @@ -1,304 +0,0 @@ -import datetime -import re -import sys -from decimal import Decimal - -from toml.decoder import InlineTableDict - -if sys.version_info >= (3,): - unicode = str - - -def dump(o, f, encoder=None): - """Writes out dict as toml to a file - - Args: - o: Object to dump into toml - f: File descriptor where the toml should be stored - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dictionary - - Raises: - TypeError: When anything other than file descriptor is passed - """ - - if not f.write: - raise TypeError("You can only dump an object to a file descriptor") - d = dumps(o, encoder=encoder) - f.write(d) - return d - - -def dumps(o, encoder=None): - """Stringifies input dict as toml - - Args: - o: Object to dump into toml - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dict - - Examples: - ```python - >>> import toml - >>> output = { - ... 'a': "I'm a string", - ... 'b': ["I'm", "a", "list"], - ... 'c': 2400 - ... } - >>> toml.dumps(output) - 'a = "I\'m a string"\nb = [ "I\'m", "a", "list",]\nc = 2400\n' - ``` - """ - - retval = "" - if encoder is None: - encoder = TomlEncoder(o.__class__) - addtoretval, sections = encoder.dump_sections(o, "") - retval += addtoretval - outer_objs = [id(o)] - while sections: - section_ids = [id(section) for section in sections.values()] - for outer_obj in outer_objs: - if outer_obj in section_ids: - raise ValueError("Circular reference detected") - outer_objs += section_ids - newsections = encoder.get_empty_table() - for section in sections: - addtoretval, addtosections = encoder.dump_sections( - sections[section], section) - - if addtoretval or (not addtoretval and not addtosections): - if retval and retval[-2:] != "\n\n": - retval += "\n" - retval += "[" + section + "]\n" - if addtoretval: - retval += addtoretval - for s in addtosections: - newsections[section + "." + s] = addtosections[s] - sections = newsections - return retval - - -def _dump_str(v): - if sys.version_info < (3,) and hasattr(v, 'decode') and isinstance(v, str): - v = v.decode('utf-8') - v = "%r" % v - if v[0] == 'u': - v = v[1:] - singlequote = v.startswith("'") - if singlequote or v.startswith('"'): - v = v[1:-1] - if singlequote: - v = v.replace("\\'", "'") - v = v.replace('"', '\\"') - v = v.split("\\x") - while len(v) > 1: - i = -1 - if not v[0]: - v = v[1:] - v[0] = v[0].replace("\\\\", "\\") - # No, I don't know why != works and == breaks - joinx = v[0][i] != "\\" - while v[0][:i] and v[0][i] == "\\": - joinx = not joinx - i -= 1 - if joinx: - joiner = "x" - else: - joiner = "u00" - v = [v[0] + joiner + v[1]] + v[2:] - return unicode('"' + v[0] + '"') - - -def _dump_float(v): - return "{}".format(v).replace("e+0", "e+").replace("e-0", "e-") - - -def _dump_time(v): - utcoffset = v.utcoffset() - if utcoffset is None: - return v.isoformat() - # The TOML norm specifies that it's local time thus we drop the offset - return v.isoformat()[:-6] - - -class TomlEncoder(object): - - def __init__(self, _dict=dict, preserve=False): - self._dict = _dict - self.preserve = preserve - self.dump_funcs = { - str: _dump_str, - unicode: _dump_str, - list: self.dump_list, - bool: lambda v: unicode(v).lower(), - int: lambda v: v, - float: _dump_float, - Decimal: _dump_float, - datetime.datetime: lambda v: v.isoformat().replace('+00:00', 'Z'), - datetime.time: _dump_time, - datetime.date: lambda v: v.isoformat() - } - - def get_empty_table(self): - return self._dict() - - def dump_list(self, v): - retval = "[" - for u in v: - retval += " " + unicode(self.dump_value(u)) + "," - retval += "]" - return retval - - def dump_inline_table(self, section): - """Preserve inline table in its compact syntax instead of expanding - into subsection. - - https://github.com/toml-lang/toml#user-content-inline-table - """ - retval = "" - if isinstance(section, dict): - val_list = [] - for k, v in section.items(): - val = self.dump_inline_table(v) - val_list.append(k + " = " + val) - retval += "{ " + ", ".join(val_list) + " }\n" - return retval - else: - return unicode(self.dump_value(section)) - - def dump_value(self, v): - # Lookup function corresponding to v's type - dump_fn = self.dump_funcs.get(type(v)) - if dump_fn is None and hasattr(v, '__iter__'): - dump_fn = self.dump_funcs[list] - # Evaluate function (if it exists) else return v - return dump_fn(v) if dump_fn is not None else self.dump_funcs[str](v) - - def dump_sections(self, o, sup): - retstr = "" - if sup != "" and sup[-1] != ".": - sup += '.' - retdict = self._dict() - arraystr = "" - for section in o: - section = unicode(section) - qsection = section - if not re.match(r'^[A-Za-z0-9_-]+$', section): - qsection = _dump_str(section) - if not isinstance(o[section], dict): - arrayoftables = False - if isinstance(o[section], list): - for a in o[section]: - if isinstance(a, dict): - arrayoftables = True - if arrayoftables: - for a in o[section]: - arraytabstr = "\n" - arraystr += "[[" + sup + qsection + "]]\n" - s, d = self.dump_sections(a, sup + qsection) - if s: - if s[0] == "[": - arraytabstr += s - else: - arraystr += s - while d: - newd = self._dict() - for dsec in d: - s1, d1 = self.dump_sections(d[dsec], sup + - qsection + "." + - dsec) - if s1: - arraytabstr += ("[" + sup + qsection + - "." + dsec + "]\n") - arraytabstr += s1 - for s1 in d1: - newd[dsec + "." + s1] = d1[s1] - d = newd - arraystr += arraytabstr - else: - if o[section] is not None: - retstr += (qsection + " = " + - unicode(self.dump_value(o[section])) + '\n') - elif self.preserve and isinstance(o[section], InlineTableDict): - retstr += (qsection + " = " + - self.dump_inline_table(o[section])) - else: - retdict[qsection] = o[section] - retstr += arraystr - return (retstr, retdict) - - -class TomlPreserveInlineDictEncoder(TomlEncoder): - - def __init__(self, _dict=dict): - super(TomlPreserveInlineDictEncoder, self).__init__(_dict, True) - - -class TomlArraySeparatorEncoder(TomlEncoder): - - def __init__(self, _dict=dict, preserve=False, separator=","): - super(TomlArraySeparatorEncoder, self).__init__(_dict, preserve) - if separator.strip() == "": - separator = "," + separator - elif separator.strip(' \t\n\r,'): - raise ValueError("Invalid separator for arrays") - self.separator = separator - - def dump_list(self, v): - t = [] - retval = "[" - for u in v: - t.append(self.dump_value(u)) - while t != []: - s = [] - for u in t: - if isinstance(u, list): - for r in u: - s.append(r) - else: - retval += " " + unicode(u) + self.separator - t = s - retval += "]" - return retval - - -class TomlNumpyEncoder(TomlEncoder): - - def __init__(self, _dict=dict, preserve=False): - import numpy as np - super(TomlNumpyEncoder, self).__init__(_dict, preserve) - self.dump_funcs[np.float16] = _dump_float - self.dump_funcs[np.float32] = _dump_float - self.dump_funcs[np.float64] = _dump_float - self.dump_funcs[np.int16] = self._dump_int - self.dump_funcs[np.int32] = self._dump_int - self.dump_funcs[np.int64] = self._dump_int - - def _dump_int(self, v): - return "{}".format(int(v)) - - -class TomlPreserveCommentEncoder(TomlEncoder): - - def __init__(self, _dict=dict, preserve=False): - from toml.decoder import CommentValue - super(TomlPreserveCommentEncoder, self).__init__(_dict, preserve) - self.dump_funcs[CommentValue] = lambda v: v.dump(self.dump_value) - - -class TomlPathlibEncoder(TomlEncoder): - - def _dump_pathlib_path(self, v): - return _dump_str(str(v)) - - def dump_value(self, v): - if (3, 4) <= sys.version_info: - import pathlib - if isinstance(v, pathlib.PurePath): - v = str(v) - return super(TomlPathlibEncoder, self).dump_value(v) diff --git a/env/lib/python3.8/site-packages/toml/ordered.py b/env/lib/python3.8/site-packages/toml/ordered.py deleted file mode 100644 index 9c20c41a..00000000 --- a/env/lib/python3.8/site-packages/toml/ordered.py +++ /dev/null @@ -1,15 +0,0 @@ -from collections import OrderedDict -from toml import TomlEncoder -from toml import TomlDecoder - - -class TomlOrderedDecoder(TomlDecoder): - - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) - - -class TomlOrderedEncoder(TomlEncoder): - - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) diff --git a/env/lib/python3.8/site-packages/toml/tz.py b/env/lib/python3.8/site-packages/toml/tz.py deleted file mode 100644 index bf20593a..00000000 --- a/env/lib/python3.8/site-packages/toml/tz.py +++ /dev/null @@ -1,24 +0,0 @@ -from datetime import tzinfo, timedelta - - -class TomlTz(tzinfo): - def __init__(self, toml_offset): - if toml_offset == "Z": - self._raw_offset = "+00:00" - else: - self._raw_offset = toml_offset - self._sign = -1 if self._raw_offset[0] == '-' else 1 - self._hours = int(self._raw_offset[1:3]) - self._minutes = int(self._raw_offset[4:6]) - - def __deepcopy__(self, memo): - return self.__class__(self._raw_offset) - - def tzname(self, dt): - return "UTC" + self._raw_offset - - def utcoffset(self, dt): - return self._sign * timedelta(hours=self._hours, minutes=self._minutes) - - def dst(self, dt): - return timedelta(0) diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/INSTALLER b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/LICENSE.md b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/LICENSE.md deleted file mode 100644 index 37edac59..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -Copyright © 2017-present, [Encode OSS Ltd](http://www.encode.io/). -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* 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 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/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/METADATA b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/METADATA deleted file mode 100644 index 0a77adf8..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/METADATA +++ /dev/null @@ -1,125 +0,0 @@ -Metadata-Version: 2.1 -Name: uvicorn -Version: 0.12.3 -Summary: The lightning-fast ASGI server. -Home-page: https://github.com/encode/uvicorn -Author: Tom Christie -Author-email: tom@tomchristie.com -License: BSD -Platform: UNKNOWN -Classifier: Development Status :: 4 - Beta -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Description-Content-Type: text/markdown -Requires-Dist: click (==7.*) -Requires-Dist: h11 (>=0.8) -Requires-Dist: typing-extensions ; python_version < "3.8" -Provides-Extra: standard -Requires-Dist: websockets (==8.*) ; extra == 'standard' -Requires-Dist: watchgod (<0.7,>=0.6) ; extra == 'standard' -Requires-Dist: python-dotenv (>=0.13.*) ; extra == 'standard' -Requires-Dist: PyYAML (>=5.1) ; extra == 'standard' -Requires-Dist: httptools (==0.1.*) ; (sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy") and extra == 'standard' -Requires-Dist: uvloop (>=0.14.0) ; (sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy") and extra == 'standard' -Requires-Dist: colorama (>=0.4.*) ; (sys_platform == "win32") and extra == 'standard' - -

    - uvicorn -

    - -

    -The lightning-fast ASGI server. -

    - ---- - -[![Build Status](https://github.com/encode/uvicorn/workflows/Test%20Suite/badge.svg)](https://github.com/encode/uvicorn/actions) -[![Package version](https://badge.fury.io/py/uvicorn.svg)](https://pypi.python.org/pypi/uvicorn) - -**Documentation**: [https://www.uvicorn.org](https://www.uvicorn.org) - -**Community**: [https://discuss.encode.io/c/uvicorn](https://discuss.encode.io/c/uvicorn) - -**Requirements**: Python 3.6+ (For Python 3.5 support, install version 0.8.6.) - -Uvicorn is a lightning-fast ASGI server implementation, using [uvloop][uvloop] and [httptools][httptools]. - -Until recently Python has lacked a minimal low-level server/application interface for -asyncio frameworks. The [ASGI specification][asgi] fills this gap, and means we're now able to -start building a common set of tooling usable across all asyncio frameworks. - -Uvicorn currently supports HTTP/1.1 and WebSockets. Support for HTTP/2 is planned. - -## Quickstart - -Install using `pip`: - -```shell -$ pip install uvicorn -``` - -This will install uvicorn with minimal (pure Python) dependencies. - -```shell -$ pip install uvicorn[standard] -``` - -This will install uvicorn with "Cython-based" dependencies (where possible) and other "optional extras". - -In this context, "Cython-based" means the following: - -- the event loop `uvloop` will be installed and used if possible. -- the http protocol will be handled by `httptools` if possible. - -Moreover, "optional extras" means that: - -- the websocket protocol will be handled by `websockets` (should you want to use `wsproto` you'd need to install it manually) if possible. -- the `--reloader` flag in development mode will use `watchgod`. -- windows users will have `colorama` installed for the colored logs. -- `python-dotenv` will be installed should you want to use the `--env-file` option. -- `PyYAML` will be installed to allow you to provide a `.yaml` file to `--log-config`, if desired. - -Create an application, in `example.py`: - -```python -async def app(scope, receive, send): - assert scope['type'] == 'http' - - await send({ - 'type': 'http.response.start', - 'status': 200, - 'headers': [ - [b'content-type', b'text/plain'], - ], - }) - await send({ - 'type': 'http.response.body', - 'body': b'Hello, world!', - }) -``` - -Run the server: - -```shell -$ uvicorn example:app -``` - ---- - -
    - -[uvloop]: https://github.com/MagicStack/uvloop -[httptools]: https://github.com/MagicStack/httptools -[asgi]: https://asgi.readthedocs.io/en/latest/ - - diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/RECORD b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/RECORD deleted file mode 100644 index 6a663d2c..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/RECORD +++ /dev/null @@ -1,86 +0,0 @@ -../../../bin/uvicorn,sha256=fuhShZpDTk-urUW_4Oh7x4IkHA3gjDkx8gUjcgpgsiU,259 -uvicorn-0.12.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -uvicorn-0.12.3.dist-info/LICENSE.md,sha256=er_Yxh9--QgfwWqJwXSYAYICU0lwug_wy0kwGfiSf_A,1525 -uvicorn-0.12.3.dist-info/METADATA,sha256=kO4Qlr_NhFyBiM1zlaDx1vv_MwLJtbdSHKhL1RQ672g,4617 -uvicorn-0.12.3.dist-info/RECORD,, -uvicorn-0.12.3.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92 -uvicorn-0.12.3.dist-info/entry_points.txt,sha256=ItiyNXf7FTLFhNbpn2fPncOvYXBK42UDxvzQWy38sqE,57 -uvicorn-0.12.3.dist-info/top_level.txt,sha256=mr7h17DVR2TBPku1HhoPCqvFGzxJZUgl22o3Fd2JlAo,162 -uvicorn/__init__.py,sha256=C65i3t_BsVEIPwPTEbe5_aHLQ66B-KeaO3hVWD6UFd4,147 -uvicorn/__main__.py,sha256=DQizy6nKP0ywhPpnCHgmRDYIMfcqZKVEzNIWQZjqtVQ,62 -uvicorn/__pycache__/__init__.cpython-38.pyc,, -uvicorn/__pycache__/__main__.cpython-38.pyc,, -uvicorn/__pycache__/_types.cpython-38.pyc,, -uvicorn/__pycache__/config.cpython-38.pyc,, -uvicorn/__pycache__/importer.cpython-38.pyc,, -uvicorn/__pycache__/logging.cpython-38.pyc,, -uvicorn/__pycache__/main.cpython-38.pyc,, -uvicorn/__pycache__/subprocess.cpython-38.pyc,, -uvicorn/__pycache__/workers.cpython-38.pyc,, -uvicorn/_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/_impl/__pycache__/__init__.cpython-38.pyc,, -uvicorn/_impl/__pycache__/asyncio.cpython-38.pyc,, -uvicorn/_impl/asyncio.py,sha256=8PRk5RkQ6Gu5MTWlKniRVuYzvnHAgvi--xzarYXAMAk,8861 -uvicorn/_types.py,sha256=Xdk_M6s_1q74-M4T5D21vJklMVHtFgMjTBsJUNd-Xa8,698 -uvicorn/config.py,sha256=tmHnssHGEQjvtluv_ii2HdWyJ9ZJl7bzLIAblzaY7lo,12679 -uvicorn/importer.py,sha256=5DZAK6aF0iD1SgFD8UeDSdJh9s4ph8Vw-E5JWhBrN4U,1131 -uvicorn/lifespan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/lifespan/__pycache__/__init__.cpython-38.pyc,, -uvicorn/lifespan/__pycache__/off.cpython-38.pyc,, -uvicorn/lifespan/__pycache__/on.cpython-38.pyc,, -uvicorn/lifespan/off.py,sha256=wjwbgYUYHwTUkMQVOt-wnNSSmEvnrrcgvq6tux_xD2o,232 -uvicorn/lifespan/on.py,sha256=oEouj24sdiIin2QtavA8TsCx3dPDptTVYfyIRelmebc,3677 -uvicorn/logging.py,sha256=4aovL3M8EOIOoxJRrg72klYBoQ7mjK-WDm3_9ctem40,4723 -uvicorn/loops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/loops/__pycache__/__init__.cpython-38.pyc,, -uvicorn/loops/__pycache__/asyncio.cpython-38.pyc,, -uvicorn/loops/__pycache__/auto.cpython-38.pyc,, -uvicorn/loops/__pycache__/uvloop.cpython-38.pyc,, -uvicorn/loops/asyncio.py,sha256=egG0UmZUx3AaFPnPZV1N3U83_Z0MYfEDnG7bvZe5usQ,438 -uvicorn/loops/auto.py,sha256=769buSOPLVIC4esOBscsRqp6bDXVws6e-X1MCABXSkk,286 -uvicorn/loops/uvloop.py,sha256=-xpj9f3mccLxoy8Oy21P8YRrj7gjKGciWoQbqNiRp4w,112 -uvicorn/main.py,sha256=Iwvh8ZA5Kwvf_HC1zN5FKU8BmThFir2j8xYaEt6sopk,9658 -uvicorn/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/middleware/__pycache__/__init__.cpython-38.pyc,, -uvicorn/middleware/__pycache__/asgi2.cpython-38.pyc,, -uvicorn/middleware/__pycache__/debug.cpython-38.pyc,, -uvicorn/middleware/__pycache__/message_logger.cpython-38.pyc,, -uvicorn/middleware/__pycache__/proxy_headers.cpython-38.pyc,, -uvicorn/middleware/__pycache__/wsgi.cpython-38.pyc,, -uvicorn/middleware/asgi2.py,sha256=2X2DLwIhYFMkxzVKwrLtSfBnLELsb3bq2J5jxWGwE64,201 -uvicorn/middleware/debug.py,sha256=kg0zueo0wNNQiUOngYhw0gwYwk4uJW1WmSku5J0l0dw,2709 -uvicorn/middleware/message_logger.py,sha256=86LXs52FR7rLMhJHPlz6NqeL6Y4qyWfhSB3kxRkJGCU,2296 -uvicorn/middleware/proxy_headers.py,sha256=bveCNx7Gx55brDUJthhzBzE5bhcSknRVH4XYzi74nUk,2011 -uvicorn/middleware/wsgi.py,sha256=pL6SahlckDYzwK1CnB-vfB6NfnfXeqdamPq1QHe_hBE,4948 -uvicorn/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/protocols/__pycache__/__init__.cpython-38.pyc,, -uvicorn/protocols/__pycache__/utils.cpython-38.pyc,, -uvicorn/protocols/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/protocols/http/__pycache__/__init__.cpython-38.pyc,, -uvicorn/protocols/http/__pycache__/auto.cpython-38.pyc,, -uvicorn/protocols/http/__pycache__/h11_impl.cpython-38.pyc,, -uvicorn/protocols/http/__pycache__/httptools_impl.cpython-38.pyc,, -uvicorn/protocols/http/auto.py,sha256=lNQwUMJ_f-KJCN4OKvy6MzhAAqn4OszeliUQCX47s2A,290 -uvicorn/protocols/http/h11_impl.py,sha256=4m32heLFr0dlE3rSSP9giN4frJFOFfb63bPnops6gjQ,18272 -uvicorn/protocols/http/httptools_impl.py,sha256=-Yyar5S_pFUpOe1QorhiDyTA9M2myVEYdWUgu_Sjh7s,19296 -uvicorn/protocols/utils.py,sha256=l2wp0gU5K1Gh7Lxcdq7ZyveCMEVXhRGv9nVhzLGvQVo,1608 -uvicorn/protocols/websockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -uvicorn/protocols/websockets/__pycache__/__init__.cpython-38.pyc,, -uvicorn/protocols/websockets/__pycache__/auto.cpython-38.pyc,, -uvicorn/protocols/websockets/__pycache__/websockets_impl.cpython-38.pyc,, -uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-38.pyc,, -uvicorn/protocols/websockets/auto.py,sha256=hYbUnWUsJQIoSZ0WKFw0ZiovmdJi-BdiOMsFHeSYetI,438 -uvicorn/protocols/websockets/websockets_impl.py,sha256=sydidEVIv_oTxXj-ELLXazP2UQE4VH9nV6a0kYEI_fk,8636 -uvicorn/protocols/websockets/wsproto_impl.py,sha256=SXGhl2fdMzgX1RLnsHCDjcsuXJe6vMIsvimWhQUv4js,11320 -uvicorn/subprocess.py,sha256=B131clsLV1iuQi49a7vXpsVhjDf0h8oe1nOXRKnMKQU,2058 -uvicorn/supervisors/__init__.py,sha256=Ok5dpg7e0kY977eUWs-X-R1o_lwjW0s9iIuQLFHccwQ,284 -uvicorn/supervisors/__pycache__/__init__.cpython-38.pyc,, -uvicorn/supervisors/__pycache__/basereload.cpython-38.pyc,, -uvicorn/supervisors/__pycache__/multiprocess.cpython-38.pyc,, -uvicorn/supervisors/__pycache__/statreload.cpython-38.pyc,, -uvicorn/supervisors/__pycache__/watchgodreload.cpython-38.pyc,, -uvicorn/supervisors/basereload.py,sha256=M1AdkplnpmVXg-THRiXcWVjcysYgmVnH6ni-WaBP1Z8,2288 -uvicorn/supervisors/multiprocess.py,sha256=Xrs0LxFv2QvEB_e5XPlEZqU690_A97fb5O358vAH-jI,1828 -uvicorn/supervisors/statreload.py,sha256=Zm9BJwVsSJTmD1Vnvo_-UFpvVulxRGEiLcvi2ApOkjI,1407 -uvicorn/supervisors/watchgodreload.py,sha256=Tss2KBc8pCBNQA6A42qUFzfrIKgPiRK1uGl-kaMvdqk,1943 -uvicorn/workers.py,sha256=zB6o7cJ5FBnz2k19Q_WjwsMkR-xOfpByLnMoRBRI74o,2565 diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/WHEEL b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/WHEEL deleted file mode 100644 index 83ff02e9..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.35.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/entry_points.txt deleted file mode 100644 index d323115e..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/entry_points.txt +++ /dev/null @@ -1,4 +0,0 @@ - - [console_scripts] - uvicorn=uvicorn.main:main - \ No newline at end of file diff --git a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/top_level.txt b/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/top_level.txt deleted file mode 100644 index 0bac4006..00000000 --- a/env/lib/python3.8/site-packages/uvicorn-0.12.3.dist-info/top_level.txt +++ /dev/null @@ -1,9 +0,0 @@ -uvicorn -uvicorn/_impl -uvicorn/lifespan -uvicorn/loops -uvicorn/middleware -uvicorn/protocols -uvicorn/protocols/http -uvicorn/protocols/websockets -uvicorn/supervisors diff --git a/env/lib/python3.8/site-packages/uvicorn/__init__.py b/env/lib/python3.8/site-packages/uvicorn/__init__.py deleted file mode 100644 index d2929d86..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from uvicorn.config import Config -from uvicorn.main import Server, main, run - -__version__ = "0.12.3" -__all__ = ["main", "run", "Config", "Server"] diff --git a/env/lib/python3.8/site-packages/uvicorn/__main__.py b/env/lib/python3.8/site-packages/uvicorn/__main__.py deleted file mode 100644 index 8a1dc979..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/__main__.py +++ /dev/null @@ -1,4 +0,0 @@ -import uvicorn - -if __name__ == "__main__": - uvicorn.main() diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index d1508e0f3c9c70f9f96c8b983f046a0bdc80629c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 376 zcmYk0u};G<5QgK#Nn2={c!>;+fii%E5E6Trip7hS#wM|d?Z{3dmDgb48F&pI!z&Z7 zz{EKS!Abt?JKz7`J*-wo5ybWDJ9~lqBP9O=LvjblT>^N-Q5z{l5eo0Pja5Pug(+4k zO`(?1jANeijL&LJXMDbk^2H}8qa69{-sneJ=ZVjD!j8gvtV*eUVh8=4ofYR7#m0tt zHVuda62LZ})01J8m9e_0CXeaUFMo@{W@`PD`(wsngp)=y=4XtRZOhnOWEa6U;A>AB zqXcoHvZ6OykXrW4iq1GPXi2)V>Kma-y>`>KMCg&Ua!8k|_s9sK-889ub)7QsZ90hZ`A#^@V+_+nxJ diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/__main__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/__main__.cpython-38.pyc deleted file mode 100644 index f87611b84d0f849b8000163b72e19a1db37a5a62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmWIL<>g`kg6g(I@peG^F^GcN&0su#MG$sH5 diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/_types.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/_types.cpython-38.pyc deleted file mode 100644 index f60162228620ea484523f4a5b53662912773592e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1365 zcmZ`&!EVz)5Z$#M$8{Z=QYdYY9FTlyT;Kvyg^Gk!RVqay^peYBywk+gUYlK~&|K+1 z@D2O|M?Pb(ocaq~VAf7aXq%08vTtU`JM(7dxYO|ouIJx=vL6;9zYLgP4uU=0>H-BP zoMvQT{;iDW*1)0!$VZ#or$p|c*2$c_HE8ATz@q?ALe+@iGq(2Q~IN?US%`iII?_kZSKuS*3-Dv(UPIa zrkCEGm%v}8NtGC%`DO0!;Z~1O02xqD2G%hF8yrq|3ADiF)+X5`i0xg>3}0^P;AMaR zpkG3AAWjP1J_D&RfY6%QPkK8>Jl26iGn-nD!nXDp6LAiVX`ivY;N#4k1I9j$<7{fN zRVDQbW3doL6`Q0KV-o8@WDCW2B3I1Wh~Mv{QISKWAdyfN0-|ABF$ra%qOnM$GES-y z=T&eEiiB4QPirF!MLY~wSgE0ig| zPd!>|7E|~Tugz1)X-%6|(>PCG=P*41RmP&96eVacn?miFx3v?iVR{t0(mXDgjR=e| z6v#V9n8;>SG^ei7t)ejOOhXQ6tyvuM7T&!*WNu@n9ld@P>RU)4J%iVv6w-yI?p{UR zQ&lXhaXDF?X-4CU7oUY(!|xx3t;L!AtLI!2_tEK|Nx~G~r_$iXDO_*d|5$ggHSXF~ zI(-oQDi>$6Ig7l>rI!?WnL!1U2RBS7ahd_2Y|RYQY-dgzH*JkqO^9yi4U0GyiyPJ3qYam}tX&DCvS^Dd%MjLzo2+mneOvwVEOc})wR1V{5gLC?jSRt diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/config.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/config.cpython-38.pyc deleted file mode 100644 index 4bb232bf8b12dbd580852d51d5b7d8d8300d6d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8671 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 diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/importer.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/importer.cpython-38.pyc deleted file mode 100644 index 0630b1698619e6fc9e9746d9b5e6444a4701021e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1164 zcmZ`&PjAyO6t|r;NxQBpNE|^?g@7WlAR#0e(=;?Tw976N+NeNLT6(=7#vh%lkA^|NIQfCN1(3P8 zYI_Gs#5}<|oXI3+UN@9JXM;p|!#MN?K}R02D2Sg4#*Z2ISbXgD!?rg#l?O@uV(FD9 zLdl-Ny2|WA~e=;(hk<3Ujf0PBmGf(jthLLb3rt_DVhyQEN@@o<9(00#_oQ?qd>Zil_ICB%PWBdoAyw$)y7g2tICb#=<#|o>{B;R zq+9H|g%#jWOCrb5&2BanUK+i5J41!L+Jl%<(OCP*Fs7Q!f6$03&rP__XR`{lL>LPh z#2uy#@T$s#fXh&ZNu1Y#vWl0fa={d8OD#^HQn*nITX`+zC9X_e!>S|({ZJ~q%cS~q~g%8r;2P@~G4;u`FvqnsJLmZOpMYj3)P+uHE%l+HeMn?8qj zb6{UQ2Z3+}o1~5%LavEXCj{4U9ri42;s!Bsq1QkoxO!bN`F*fyn*0v@RC(j1!v^zE Y=S`Y3aAsN8O(S$GIY!<52j6Br6#xJL diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/logging.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/logging.cpython-38.pyc deleted file mode 100644 index 6750acdb381e53f19928869e8622e38fc20a76b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5690 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 PRK@vUU#t~Q74`oEZiOkL diff --git a/env/lib/python3.8/site-packages/uvicorn/__pycache__/subprocess.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/__pycache__/subprocess.cpython-38.pyc deleted file mode 100644 index 9073f64c8d39491b7a32f8a5ff3ede10f942826f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1940 zcmeHIKabls6elIw(y8&K2{N=m2TpB$$XP>{1_+9_X@@S?0B+FMi$aUD?8tL^6oGDnp?LMCL-zyjeb>E|sE<9K z;SP=9exs#wqdXiqVUh=XKl}7TR@$iD=E`sIkUQ2fU_g^t-`Q))?V zsxgf_0 zY5Sc}n|?R`#u#l(+Z@sL(Ae|tGLmH4j?6r}$ z$RVK{Q053xWc-h-z0)ysWuUC}Y=-{=>&k@y+U+7TsJo-2Kg_?klTL%=!WK42^3C)aOkezO-nAFYy+P0dMnV7@Myw*P};2*(d!g@QPGLhLdbs96RL9<7kiy3?L6Gw ze%$G0sVYZ8c6w2gM9&g&)7X!F~^p|&z+hrC0bs=RYA001G`KSlMRo#YmqCBTzk_{LH7c!Nu z7V$`AWx@7^$XS%c2ZAn7WocH#{Udz=taXQe=fhfKOT1f4Hj5ZC}3`iZok>Ck9tOEr~;y@(YOU%&BWtK;Ss1P)) zqG4t@y*^k(><#p~QA01W!qL_|!g2{keykX5s&YQd3&2ik2VByAnR762mM*|irM-hF zDTQuteZTYQ@izPB>BAqkcO_OJ?N{ON`r1_@>1#KVFu~u42;zu)6_U0qEmnzXXn-~< zXGAv{GX;gQGwa_w8^tK!$m4viOmjd|@U_D|A(FLQNql?sS#q>dr{YFci`064B(H!c ztI*Va=q$2ohonVTh(8@2o7luBu6g}`{4lUvpfP*@@tdK&0`pq-@zsUOw>}NqLZ!i~ zgS*G3K72c{(FIT~B@jT66`1S>_Dlm=+MVESHx-TqQ`$ zqz42S57-%zpW>Gr*xkf#4Z98K?m<&{F1^~&t^-$@zcr&~ ztLe%k6%W!VQ4esU4W0GwMQgQ%MG+oMezWLZAP^>Kgc*>Agp=3ggcRF(sHqfHM;v5hMOqjg{@Dbr}k$@auTnqu| zEP#NhBW`~{Q!VJm*2J3ThKT@P@>M;Q?+AlAz>jfqjs8cA>%CP{yGvMV(r6^0)P#(U zGF~P~w-|d~MoImp!5GhajLDC|vN=B{x#T9YpJRu0L$~Xr*%L_u%IA2P#56gH0Y+W5 z3|&B6FSJ`XT5jM3zDevJh!-9QxChYGRp`!tT=2IAep=wy1+E}ZuhhHzdULb-2a$I` zojQA)n-VYjovtgtfKh&l-B;L|t(?0!i<`tF^BpvUU_cDt4UIvGPS7iZ`Zs2MT2!7z zkOv4jon3uZ2{ToXw#xc`97S^=7J9HRe`vV>0r_zAW(#`3^^-X{{faa Byv6_k diff --git a/env/lib/python3.8/site-packages/uvicorn/_impl/__init__.py b/env/lib/python3.8/site-packages/uvicorn/_impl/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 441e638e9c11b71debae9583068920eabcde8d24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmWIL<>g`k0?X-#;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_Uenx(7s(x{5 za#3nYeqO46dS*#{QEEYcv3_Y@rhY+Ua!E#NZepHpacWUnYLR|wUYUMQW|DqEWl2VU zp0S>VesN|=sxDAnc4B%eP*YiEa(+>setc$bL5_ZWd}bcdym-BW%3B;Zx%nxjIjMFa J7kma{1^|deG}{0G diff --git a/env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/asyncio.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/_impl/__pycache__/asyncio.cpython-38.pyc deleted file mode 100644 index 514513bd2d021241b928ffe85c90b77208896ece..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6200 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 Pc3^_Pyl+)JvswQyF^BHC diff --git a/env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py b/env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py deleted file mode 100644 index 3331fcc4..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/_impl/asyncio.py +++ /dev/null @@ -1,256 +0,0 @@ -import asyncio -import functools -import logging -import os -import platform -import signal -import socket -import sys -import time -from email.utils import formatdate - -import click - -HANDLED_SIGNALS = ( - signal.SIGINT, # Unix signal 2. Sent by Ctrl+C. - signal.SIGTERM, # Unix signal 15. Sent by `kill `. -) - -logger = logging.getLogger("uvicorn.error") - - -class AsyncioServerState: - """ - Shared servers state that is available between all protocol instances. - """ - - def __init__(self): - self.total_requests = 0 - self.connections = set() - self.tasks = set() - self.default_headers = [] - - -class AsyncioServer: - def __init__(self, config): - self.config = config - self.server_state = AsyncioServerState() - - self.started = False - self.should_exit = False - self.force_exit = False - self.last_notified = 0 - - def run(self, sockets=None): - self.config.setup_event_loop() - loop = asyncio.get_event_loop() - loop.run_until_complete(self.serve(sockets=sockets)) - - async def serve(self, sockets=None): - process_id = os.getpid() - - config = self.config - if not config.loaded: - config.load() - - self.lifespan = config.lifespan_class(config) - - self.install_signal_handlers() - - message = "Started server process [%d]" - color_message = "Started server process [" + click.style("%d", fg="cyan") + "]" - logger.info(message, process_id, extra={"color_message": color_message}) - - await self.startup(sockets=sockets) - if self.should_exit: - return - await self.main_loop() - await self.shutdown(sockets=sockets) - - message = "Finished server process [%d]" - color_message = "Finished server process [" + click.style("%d", fg="cyan") + "]" - logger.info( - "Finished server process [%d]", - process_id, - extra={"color_message": color_message}, - ) - - async def startup(self, sockets=None): - await self.lifespan.startup() - if self.lifespan.should_exit: - self.should_exit = True - return - - config = self.config - - create_protocol = functools.partial( - config.http_protocol_class, config=config, server_state=self.server_state - ) - - loop = asyncio.get_event_loop() - - if sockets is not None: - # Explicitly passed a list of open sockets. - # We use this when the server is run from a Gunicorn worker. - - def _share_socket(sock: socket) -> socket: - # Windows requires the socket be explicitly shared across - # multiple workers (processes). - from socket import fromshare # type: ignore - - sock_data = sock.share(os.getpid()) # type: ignore - return fromshare(sock_data) - - self.servers = [] - for sock in sockets: - if config.workers > 1 and platform.system() == "Windows": - sock = _share_socket(sock) - server = await loop.create_server( - create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog - ) - self.servers.append(server) - - elif config.fd is not None: - # Use an existing socket, from a file descriptor. - sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM) - server = await loop.create_server( - create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog - ) - message = "Uvicorn running on socket %s (Press CTRL+C to quit)" - logger.info(message % str(sock.getsockname())) - self.servers = [server] - - elif config.uds is not None: - # Create a socket using UNIX domain socket. - uds_perms = 0o666 - if os.path.exists(config.uds): - uds_perms = os.stat(config.uds).st_mode - server = await loop.create_unix_server( - create_protocol, path=config.uds, ssl=config.ssl, backlog=config.backlog - ) - os.chmod(config.uds, uds_perms) - message = "Uvicorn running on unix socket %s (Press CTRL+C to quit)" - logger.info(message % config.uds) - self.servers = [server] - - else: - # Standard case. Create a socket from a host/port pair. - addr_format = "%s://%s:%d" - if config.host and ":" in config.host: - # It's an IPv6 address. - addr_format = "%s://[%s]:%d" - - try: - server = await loop.create_server( - create_protocol, - host=config.host, - port=config.port, - ssl=config.ssl, - backlog=config.backlog, - ) - except OSError as exc: - logger.error(exc) - await self.lifespan.shutdown() - sys.exit(1) - port = config.port - if port == 0: - port = server.sockets[0].getsockname()[1] - protocol_name = "https" if config.ssl else "http" - message = f"Uvicorn running on {addr_format} (Press CTRL+C to quit)" - color_message = ( - "Uvicorn running on " - + click.style(addr_format, bold=True) - + " (Press CTRL+C to quit)" - ) - logger.info( - message, - protocol_name, - config.host, - port, - extra={"color_message": color_message}, - ) - self.servers = [server] - - self.started = True - - async def main_loop(self): - counter = 0 - should_exit = await self.on_tick(counter) - while not should_exit: - counter += 1 - counter = counter % 864000 - await asyncio.sleep(0.1) - should_exit = await self.on_tick(counter) - - async def on_tick(self, counter) -> bool: - # Update the default headers, once per second. - if counter % 10 == 0: - current_time = time.time() - current_date = formatdate(current_time, usegmt=True).encode() - self.server_state.default_headers = [ - (b"date", current_date) - ] + self.config.encoded_headers - - # Callback to `callback_notify` once every `timeout_notify` seconds. - if self.config.callback_notify is not None: - if current_time - self.last_notified > self.config.timeout_notify: - self.last_notified = current_time - await self.config.callback_notify() - - # Determine if we should exit. - if self.should_exit: - return True - if self.config.limit_max_requests is not None: - return self.server_state.total_requests >= self.config.limit_max_requests - return False - - async def shutdown(self, sockets=None): - logger.info("Shutting down") - - # Stop accepting new connections. - for server in self.servers: - server.close() - for sock in sockets or []: - sock.close() - for server in self.servers: - await server.wait_closed() - - # Request shutdown on all existing connections. - for connection in list(self.server_state.connections): - connection.shutdown() - await asyncio.sleep(0.1) - - # Wait for existing connections to finish sending responses. - if self.server_state.connections and not self.force_exit: - msg = "Waiting for connections to close. (CTRL+C to force quit)" - logger.info(msg) - while self.server_state.connections and not self.force_exit: - await asyncio.sleep(0.1) - - # Wait for existing tasks to complete. - if self.server_state.tasks and not self.force_exit: - msg = "Waiting for background tasks to complete. (CTRL+C to force quit)" - logger.info(msg) - while self.server_state.tasks and not self.force_exit: - await asyncio.sleep(0.1) - - # Send the lifespan shutdown event, and wait for application shutdown. - if not self.force_exit: - await self.lifespan.shutdown() - - def install_signal_handlers(self): - loop = asyncio.get_event_loop() - - try: - for sig in HANDLED_SIGNALS: - loop.add_signal_handler(sig, self.handle_exit, sig, None) - except NotImplementedError: - # Windows - for sig in HANDLED_SIGNALS: - signal.signal(sig, self.handle_exit) - - def handle_exit(self, sig, frame): - if self.should_exit: - self.force_exit = True - else: - self.should_exit = True diff --git a/env/lib/python3.8/site-packages/uvicorn/_types.py b/env/lib/python3.8/site-packages/uvicorn/_types.py deleted file mode 100644 index d7967c24..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/_types.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys -from typing import Optional - -if sys.version_info < (3, 8): - from typing_extensions import Literal, TypedDict -else: - from typing import Literal, TypedDict - - -class ASGISpecInfo(TypedDict): - version: str - spec_version: Optional[Literal["2.0", "2.1"]] - - -class LifespanScope(TypedDict): - type: Literal["lifespan"] - asgi: ASGISpecInfo - - -class LifespanReceiveMessage(TypedDict): - type: Literal["lifespan.startup", "lifespan.shutdown"] - - -class LifespanSendMessage(TypedDict): - type: Literal[ - "lifespan.startup.complete", - "lifespan.startup.failed", - "lifespan.shutdown.complete", - "lifespan.shutdown.failed", - ] - message: Optional[str] diff --git a/env/lib/python3.8/site-packages/uvicorn/config.py b/env/lib/python3.8/site-packages/uvicorn/config.py deleted file mode 100644 index 0b7bd1ef..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/config.py +++ /dev/null @@ -1,379 +0,0 @@ -import asyncio -import inspect -import json -import logging -import logging.config -import os -import socket -import ssl -import sys -from typing import List, Tuple - -import click - -try: - import yaml -except ImportError: - # If the code below that depends on yaml is exercised, it will raise a NameError. - # Install the PyYAML package or the uvicorn[standard] optional dependencies to - # enable this functionality. - pass - -from uvicorn.importer import ImportFromStringError, import_from_string -from uvicorn.middleware.asgi2 import ASGI2Middleware -from uvicorn.middleware.debug import DebugMiddleware -from uvicorn.middleware.message_logger import MessageLoggerMiddleware -from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware -from uvicorn.middleware.wsgi import WSGIMiddleware - -TRACE_LOG_LEVEL = 5 - -LOG_LEVELS = { - "critical": logging.CRITICAL, - "error": logging.ERROR, - "warning": logging.WARNING, - "info": logging.INFO, - "debug": logging.DEBUG, - "trace": TRACE_LOG_LEVEL, -} -HTTP_PROTOCOLS = { - "auto": "uvicorn.protocols.http.auto:AutoHTTPProtocol", - "h11": "uvicorn.protocols.http.h11_impl:H11Protocol", - "httptools": "uvicorn.protocols.http.httptools_impl:HttpToolsProtocol", -} -WS_PROTOCOLS = { - "auto": "uvicorn.protocols.websockets.auto:AutoWebSocketsProtocol", - "none": None, - "websockets": "uvicorn.protocols.websockets.websockets_impl:WebSocketProtocol", - "wsproto": "uvicorn.protocols.websockets.wsproto_impl:WSProtocol", -} -LIFESPAN = { - "auto": "uvicorn.lifespan.on:LifespanOn", - "on": "uvicorn.lifespan.on:LifespanOn", - "off": "uvicorn.lifespan.off:LifespanOff", -} -LOOP_SETUPS = { - "none": None, - "auto": "uvicorn.loops.auto:auto_loop_setup", - "asyncio": "uvicorn.loops.asyncio:asyncio_setup", - "uvloop": "uvicorn.loops.uvloop:uvloop_setup", -} -INTERFACES = ["auto", "asgi3", "asgi2", "wsgi"] - - -# Fallback to 'ssl.PROTOCOL_SSLv23' in order to support Python < 3.5.3. -SSL_PROTOCOL_VERSION = getattr(ssl, "PROTOCOL_TLS", ssl.PROTOCOL_SSLv23) - - -LOGGING_CONFIG = { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "default": { - "()": "uvicorn.logging.DefaultFormatter", - "fmt": "%(levelprefix)s %(message)s", - "use_colors": None, - }, - "access": { - "()": "uvicorn.logging.AccessFormatter", - "fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501 - }, - }, - "handlers": { - "default": { - "formatter": "default", - "class": "logging.StreamHandler", - "stream": "ext://sys.stderr", - }, - "access": { - "formatter": "access", - "class": "logging.StreamHandler", - "stream": "ext://sys.stdout", - }, - }, - "loggers": { - "uvicorn": {"handlers": ["default"], "level": "INFO"}, - "uvicorn.error": {"level": "INFO"}, - "uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False}, - }, -} - -logger = logging.getLogger("uvicorn.error") - - -def create_ssl_context( - certfile, keyfile, password, ssl_version, cert_reqs, ca_certs, ciphers -): - ctx = ssl.SSLContext(ssl_version) - get_password = (lambda: password) if password else None - ctx.load_cert_chain(certfile, keyfile, get_password) - ctx.verify_mode = cert_reqs - if ca_certs: - ctx.load_verify_locations(ca_certs) - if ciphers: - ctx.set_ciphers(ciphers) - return ctx - - -class Config: - def __init__( - self, - app, - host="127.0.0.1", - port=8000, - uds=None, - fd=None, - loop="auto", - http="auto", - ws="auto", - lifespan="auto", - env_file=None, - log_config=LOGGING_CONFIG, - log_level=None, - access_log=True, - use_colors=None, - interface="auto", - debug=False, - reload=False, - reload_dirs=None, - reload_delay=None, - workers=None, - proxy_headers=True, - forwarded_allow_ips=None, - root_path="", - limit_concurrency=None, - limit_max_requests=None, - backlog=2048, - timeout_keep_alive=5, - timeout_notify=30, - callback_notify=None, - ssl_keyfile=None, - ssl_certfile=None, - ssl_keyfile_password=None, - ssl_version=SSL_PROTOCOL_VERSION, - ssl_cert_reqs=ssl.CERT_NONE, - ssl_ca_certs=None, - ssl_ciphers="TLSv1", - headers=None, - ): - self.app = app - self.host = host - self.port = port - self.uds = uds - self.fd = fd - self.loop = loop - self.http = http - self.ws = ws - self.lifespan = lifespan - self.log_config = log_config - self.log_level = log_level - self.access_log = access_log - self.use_colors = use_colors - self.interface = interface - self.debug = debug - self.reload = reload - self.reload_delay = reload_delay or 0.25 - self.workers = workers or 1 - self.proxy_headers = proxy_headers - self.root_path = root_path - self.limit_concurrency = limit_concurrency - self.limit_max_requests = limit_max_requests - self.backlog = backlog - self.timeout_keep_alive = timeout_keep_alive - self.timeout_notify = timeout_notify - self.callback_notify = callback_notify - self.ssl_keyfile = ssl_keyfile - self.ssl_certfile = ssl_certfile - self.ssl_keyfile_password = ssl_keyfile_password - self.ssl_version = ssl_version - self.ssl_cert_reqs = ssl_cert_reqs - self.ssl_ca_certs = ssl_ca_certs - self.ssl_ciphers = ssl_ciphers - self.headers = headers if headers else [] # type: List[str] - self.encoded_headers = None # type: List[Tuple[bytes, bytes]] - - self.loaded = False - self.configure_logging() - - if reload_dirs is None: - self.reload_dirs = [os.getcwd()] - else: - self.reload_dirs = reload_dirs - - if env_file is not None: - from dotenv import load_dotenv - - logger.info("Loading environment from '%s'", env_file) - load_dotenv(dotenv_path=env_file) - - if workers is None and "WEB_CONCURRENCY" in os.environ: - self.workers = int(os.environ["WEB_CONCURRENCY"]) - - if forwarded_allow_ips is None: - self.forwarded_allow_ips = os.environ.get( - "FORWARDED_ALLOW_IPS", "127.0.0.1" - ) - else: - self.forwarded_allow_ips = forwarded_allow_ips - - @property - def asgi_version(self) -> str: - return {"asgi2": "2.0", "asgi3": "3.0", "wsgi": "3.0"}[self.interface] - - @property - def is_ssl(self) -> bool: - return bool(self.ssl_keyfile or self.ssl_certfile) - - def configure_logging(self): - logging.addLevelName(TRACE_LOG_LEVEL, "TRACE") - - if self.log_config is not None: - if isinstance(self.log_config, dict): - if self.use_colors in (True, False): - self.log_config["formatters"]["default"][ - "use_colors" - ] = self.use_colors - self.log_config["formatters"]["access"][ - "use_colors" - ] = self.use_colors - logging.config.dictConfig(self.log_config) - elif self.log_config.endswith(".json"): - with open(self.log_config) as file: - loaded_config = json.load(file) - logging.config.dictConfig(loaded_config) - elif self.log_config.endswith((".yaml", ".yml")): - with open(self.log_config) as file: - loaded_config = yaml.safe_load(file) - logging.config.dictConfig(loaded_config) - else: - # See the note about fileConfig() here: - # https://docs.python.org/3/library/logging.config.html#configuration-file-format - logging.config.fileConfig( - self.log_config, disable_existing_loggers=False - ) - - if self.log_level is not None: - if isinstance(self.log_level, str): - log_level = LOG_LEVELS[self.log_level] - else: - log_level = self.log_level - logging.getLogger("uvicorn.error").setLevel(log_level) - logging.getLogger("uvicorn.access").setLevel(log_level) - logging.getLogger("uvicorn.asgi").setLevel(log_level) - if self.access_log is False: - logging.getLogger("uvicorn.access").handlers = [] - logging.getLogger("uvicorn.access").propagate = False - - def load(self): - assert not self.loaded - - if self.is_ssl: - self.ssl = create_ssl_context( - keyfile=self.ssl_keyfile, - certfile=self.ssl_certfile, - password=self.ssl_keyfile_password, - ssl_version=self.ssl_version, - cert_reqs=self.ssl_cert_reqs, - ca_certs=self.ssl_ca_certs, - ciphers=self.ssl_ciphers, - ) - else: - self.ssl = None - - encoded_headers = [ - (key.lower().encode("latin1"), value.encode("latin1")) - for key, value in self.headers - ] - self.encoded_headers = ( - encoded_headers - if b"server" in dict(encoded_headers) - else [(b"server", b"uvicorn")] + encoded_headers - ) # type: List[Tuple[bytes, bytes]] - - if isinstance(self.http, str): - self.http_protocol_class = import_from_string(HTTP_PROTOCOLS[self.http]) - else: - self.http_protocol_class = self.http - - if isinstance(self.ws, str): - self.ws_protocol_class = import_from_string(WS_PROTOCOLS[self.ws]) - else: - self.ws_protocol_class = self.ws - - self.lifespan_class = import_from_string(LIFESPAN[self.lifespan]) - - try: - self.loaded_app = import_from_string(self.app) - except ImportFromStringError as exc: - logger.error("Error loading ASGI app. %s" % exc) - sys.exit(1) - - if self.interface == "auto": - if inspect.isclass(self.loaded_app): - use_asgi_3 = hasattr(self.loaded_app, "__await__") - elif inspect.isfunction(self.loaded_app): - use_asgi_3 = asyncio.iscoroutinefunction(self.loaded_app) - else: - call = getattr(self.loaded_app, "__call__", None) - use_asgi_3 = asyncio.iscoroutinefunction(call) - self.interface = "asgi3" if use_asgi_3 else "asgi2" - - if self.interface == "wsgi": - self.loaded_app = WSGIMiddleware(self.loaded_app) - self.ws_protocol_class = None - elif self.interface == "asgi2": - self.loaded_app = ASGI2Middleware(self.loaded_app) - - if self.debug: - self.loaded_app = DebugMiddleware(self.loaded_app) - if logger.level <= TRACE_LOG_LEVEL: - self.loaded_app = MessageLoggerMiddleware(self.loaded_app) - if self.proxy_headers: - self.loaded_app = ProxyHeadersMiddleware( - self.loaded_app, trusted_hosts=self.forwarded_allow_ips - ) - - self.loaded = True - - def setup_event_loop(self): - loop_setup = import_from_string(LOOP_SETUPS[self.loop]) - if loop_setup is not None: - loop_setup() - - def bind_socket(self): - family = socket.AF_INET - addr_format = "%s://%s:%d" - - if self.host and ":" in self.host: - # It's an IPv6 address. - family = socket.AF_INET6 - addr_format = "%s://[%s]:%d" - - sock = socket.socket(family=family) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - try: - sock.bind((self.host, self.port)) - except OSError as exc: - logger.error(exc) - sys.exit(1) - sock.set_inheritable(True) - - message = f"Uvicorn running on {addr_format} (Press CTRL+C to quit)" - color_message = ( - "Uvicorn running on " - + click.style(addr_format, bold=True) - + " (Press CTRL+C to quit)" - ) - protocol_name = "https" if self.is_ssl else "http" - logger.info( - message, - protocol_name, - self.host, - self.port, - extra={"color_message": color_message}, - ) - return sock - - @property - def should_reload(self): - return isinstance(self.app, str) and (self.debug or self.reload) diff --git a/env/lib/python3.8/site-packages/uvicorn/importer.py b/env/lib/python3.8/site-packages/uvicorn/importer.py deleted file mode 100644 index 29ede97d..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/importer.py +++ /dev/null @@ -1,37 +0,0 @@ -import importlib - - -class ImportFromStringError(Exception): - pass - - -def import_from_string(import_str): - if not isinstance(import_str, str): - return import_str - - module_str, _, attrs_str = import_str.partition(":") - if not module_str or not attrs_str: - message = ( - 'Import string "{import_str}" must be in format ":".' - ) - raise ImportFromStringError(message.format(import_str=import_str)) - - try: - module = importlib.import_module(module_str) - except ImportError as exc: - if exc.name != module_str: - raise exc from None - message = 'Could not import module "{module_str}".' - raise ImportFromStringError(message.format(module_str=module_str)) - - instance = module - try: - for attr_str in attrs_str.split("."): - instance = getattr(instance, attr_str) - except AttributeError: - message = 'Attribute "{attrs_str}" not found in module "{module_str}".' - raise ImportFromStringError( - message.format(attrs_str=attrs_str, module_str=module_str) - ) - - return instance diff --git a/env/lib/python3.8/site-packages/uvicorn/lifespan/__init__.py b/env/lib/python3.8/site-packages/uvicorn/lifespan/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 128702345be4b974b5b1c7216ca422a631bc5022..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmWIL<>g`k0?X-#;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_^enx(7s(x{5 za#3nYeqO46dS*#{QEEYcv3_Y@rhY+Ua!E#NZepHpacWUnYLR|wUYUMQW|DqEWl2VU zp0S>VesN|=sxDAnc4B%eP*YiEa(+=BP)%BDaY169etdjp9?-~my@JYH95%W6DWy57 Lb|6Q524V&PHUBmr diff --git a/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/off.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/off.cpython-38.pyc deleted file mode 100644 index 1eb4e3e4aba19cbdbb81181336639368763d7cf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 778 zcmah{y^hpC3?3)hB)2~Z32OQjdqIfe3WShOf(9)GqDeD~;t3lu`C%sEIH2RiQ``&e zYrtEirGZzV!cI0vkdUxskG~nq-)ASUHk+j&`}pOn{6Xh;26J->JR!IDD4;;lqJ#uM zJQL`kdnM5Q>?96)FGaNYNi`yZ-aoIaym*~4oZC&aGrCnG0ThX&Tm*EksTq1#Ug8m2 zTm$+T5Lz5jh$n=61fp5?tLH_oY?D?m@_ZLLy`K$yy>C?8nJRN;q@1&#lUtq@;ggUw z3UzXJPa{ZHc3*cIrFvhq)XcL==f%iN=qeWzm&49vD2KdrF`3^dVDdw9dp8A&0)h~p!*Y;*zixp%dk9t2)Er^ e?r^t@+$1=Dh_M-0{;NeFJ{mPV=IsvJ*Y0mtKc4Xb diff --git a/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/on.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/lifespan/__pycache__/on.cpython-38.pyc deleted file mode 100644 index 0c2dee933697c896a3df9a0d4b977240ce5ae543..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3264 zcmZ`*Pmdc(6|d@UclY$zo=G+&J3)&aSZ%OS>?H`ayP&YcY6y{riI^FfU~2%lo=q$d2a*F9u5ii0vnN*Kz-Iu76CVKe5hNtOLJo-EtL~oINoc!YzxS$M{dw>A zUe!+U|Kw1Rt?p@#Q@Z*&4C2)w4M1?2$codXC|p zQElw@+_Bg5#(vL-uGU+-&x9+yXH0lctzIDb0c-pJ!MJR%&GXt%rgAF5xSyoSaXe_- z`SsoSSn5fX?90B4&*YD#*3m%bjY@yePbV^e>r#}7DErLr-cPeuoSa3YShRE&WwMp2 zDA92ir%4O{Q8{*NqS7qwr=w1vma_a@ZeBnu8Ev>{Nn3DXJ-37{oM+fBq}p?CHsw7I1eh;>Mw^dZ+_*$_?0YcepF8)6gEx^c&qJg7GFFxhKcx!X6+$Xz9~sY?3R z()x&}C4PceAA-#Jkm=@}FZc!HkmfA3GJAm~UJzf)+=X|+!19J&XIPN;*=hRQ<5Mk-MWb5>n(2eU*>7b8nOm25~aT*9J1%1uqqKGhZ*# zPm+F|=Cz$OnPhnb0a4j>5=tXB^~p37>1RnHE81AzP({$gUlA_yhM7A|`~9iH#La4i z<0u|MUe_n-bRS(7qJ)33$eqL4J8$aNPsfvy%w(s%sZg<4?!*Zeu|aGT&?_($ zj?#3JuOryV{4k63Y3_`pI8kp=KYKFG)D>g=8TO&R1XfY73Ml*4qVt+Tow|;uwxwuto|w`NygW_IO_l~_~UFJrw6f&8ulNX~q3{at zQ9RT;M99tR77_A>`YOm5+&J)6*ZI{XUq>HJX+s&~z-RE?YNk{@SKL;E0i9tcMg9(E z_UGAm$Vo%z9EoDM8o3LF*LiN8Td0eubVGo9=smTogg9bJ=CI5^4b-1FJGVKT{Y=2| z;hLy{2I#%6hDYq@?DKm^?DO3+EcUQ2TqMqKg?El595xosxp8`OP56aoxG{I;wpjZe zPRS$oZ6xHm{cHOXMoO$lMguz}n5o%pXcgQe^h2rzd+KYnC;M*aebhA%rAgxe%jFNj)f32%l9KQY{#~k5`i=1D1Tt;`RT! z&P^bS>aWY2z?XykbohH#z-Jpvxk+V$Tsv7Mfu;*&VjQn+=WhEy_vD! zpdcIB1}=6HTO{HIQ=N=u_EU~lHgt^U<0TEJ^37TD`_h(*@gFa3hf6&R+xe2Fv^6+& zaTs{Qz2NGfutv$pcNZ%ZQ;WB+4CW7cJ`=Txv7lQhj60$2;@+GKj#J1hdbfn{`TI%gTn_8_rjh1{fGMn8ap%!VJWw9BotUOFe-|8F$>)bUe<7R7vg=q zx&^}crd#J%@vB?KHvnn^ezlZV5JQk&sYz7I2_>c`ZGwTfO@ None: - self.should_exit = False - - async def startup(self) -> None: - pass - - async def shutdown(self) -> None: - pass diff --git a/env/lib/python3.8/site-packages/uvicorn/lifespan/on.py b/env/lib/python3.8/site-packages/uvicorn/lifespan/on.py deleted file mode 100644 index 0f0644fe..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/lifespan/on.py +++ /dev/null @@ -1,97 +0,0 @@ -import asyncio -import logging -from asyncio import Queue - -from uvicorn import Config -from uvicorn._types import LifespanReceiveMessage, LifespanScope, LifespanSendMessage - -STATE_TRANSITION_ERROR = "Got invalid state transition on lifespan protocol." - - -class LifespanOn: - def __init__(self, config: Config) -> None: - if not config.loaded: - config.load() - - self.config = config - self.logger = logging.getLogger("uvicorn.error") - self.startup_event = asyncio.Event() - self.shutdown_event = asyncio.Event() - self.receive_queue: "Queue[LifespanReceiveMessage]" = asyncio.Queue() - self.error_occured = False - self.startup_failed = False - self.should_exit = False - - async def startup(self) -> None: - self.logger.info("Waiting for application startup.") - - loop = asyncio.get_event_loop() - loop.create_task(self.main()) - - await self.receive_queue.put({"type": "lifespan.startup"}) - await self.startup_event.wait() - - if self.startup_failed or (self.error_occured and self.config.lifespan == "on"): - self.logger.error("Application startup failed. Exiting.") - self.should_exit = True - else: - self.logger.info("Application startup complete.") - - async def shutdown(self) -> None: - if self.error_occured: - return - self.logger.info("Waiting for application shutdown.") - await self.receive_queue.put({"type": "lifespan.shutdown"}) - await self.shutdown_event.wait() - self.logger.info("Application shutdown complete.") - - async def main(self) -> None: - try: - app = self.config.loaded_app - scope: LifespanScope = { - "type": "lifespan", - "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"}, - } - await app(scope, self.receive, self.send) - except BaseException as exc: - self.asgi = None - self.error_occured = True - if self.startup_failed: - return - if self.config.lifespan == "auto": - msg = "ASGI 'lifespan' protocol appears unsupported." - self.logger.info(msg) - else: - msg = "Exception in 'lifespan' protocol\n" - self.logger.error(msg, exc_info=exc) - finally: - self.startup_event.set() - self.shutdown_event.set() - - async def send(self, message: LifespanSendMessage) -> None: - assert message["type"] in ( - "lifespan.startup.complete", - "lifespan.startup.failed", - "lifespan.shutdown.complete", - ) - - if message["type"] == "lifespan.startup.complete": - assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR - assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR - self.startup_event.set() - - elif message["type"] == "lifespan.startup.failed": - assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR - assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR - self.startup_event.set() - self.startup_failed = True - if message.get("message"): - self.logger.error(message["message"]) - - elif message["type"] == "lifespan.shutdown.complete": - assert self.startup_event.is_set(), STATE_TRANSITION_ERROR - assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR - self.shutdown_event.set() - - async def receive(self) -> LifespanReceiveMessage: - return await self.receive_queue.get() diff --git a/env/lib/python3.8/site-packages/uvicorn/logging.py b/env/lib/python3.8/site-packages/uvicorn/logging.py deleted file mode 100644 index 1efaf92b..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/logging.py +++ /dev/null @@ -1,132 +0,0 @@ -import http -import logging -import sys -import urllib -from copy import copy - -import click - -TRACE_LOG_LEVEL = 5 - - -class ColourizedFormatter(logging.Formatter): - """ - A custom log formatter class that: - - * Outputs the LOG_LEVEL with an appropriate color. - * If a log call includes an `extras={"color_message": ...}` it will be used - for formatting the output, instead of the plain text message. - """ - - level_name_colors = { - TRACE_LOG_LEVEL: lambda level_name: click.style(str(level_name), fg="blue"), - logging.DEBUG: lambda level_name: click.style(str(level_name), fg="cyan"), - logging.INFO: lambda level_name: click.style(str(level_name), fg="green"), - logging.WARNING: lambda level_name: click.style(str(level_name), fg="yellow"), - logging.ERROR: lambda level_name: click.style(str(level_name), fg="red"), - logging.CRITICAL: lambda level_name: click.style( - str(level_name), fg="bright_red" - ), - } - - def __init__(self, fmt=None, datefmt=None, style="%", use_colors=None): - if use_colors in (True, False): - self.use_colors = use_colors - else: - self.use_colors = sys.stdout.isatty() - super().__init__(fmt=fmt, datefmt=datefmt, style=style) - - def color_level_name(self, level_name, level_no): - def default(level_name): - return str(level_name) - - func = self.level_name_colors.get(level_no, default) - return func(level_name) - - def should_use_colors(self): - return True - - def formatMessage(self, record): - recordcopy = copy(record) - levelname = recordcopy.levelname - seperator = " " * (8 - len(recordcopy.levelname)) - if self.use_colors: - levelname = self.color_level_name(levelname, recordcopy.levelno) - if "color_message" in recordcopy.__dict__: - recordcopy.msg = recordcopy.__dict__["color_message"] - recordcopy.__dict__["message"] = recordcopy.getMessage() - recordcopy.__dict__["levelprefix"] = levelname + ":" + seperator - return super().formatMessage(recordcopy) - - -class DefaultFormatter(ColourizedFormatter): - def should_use_colors(self): - return sys.stderr.isatty() - - -class AccessFormatter(ColourizedFormatter): - status_code_colours = { - 1: lambda code: click.style(str(code), fg="bright_white"), - 2: lambda code: click.style(str(code), fg="green"), - 3: lambda code: click.style(str(code), fg="yellow"), - 4: lambda code: click.style(str(code), fg="red"), - 5: lambda code: click.style(str(code), fg="bright_red"), - } - - def get_client_addr(self, scope): - client = scope.get("client") - if not client: - return "" - return "%s:%d" % (client[0], client[1]) - - def get_path(self, scope): - return urllib.parse.quote(scope.get("root_path", "") + scope["path"]) - - def get_full_path(self, scope): - path = scope.get("root_path", "") + scope["path"] - query_string = scope.get("query_string", b"").decode("ascii") - if query_string: - return urllib.parse.quote(path) + "?" + query_string - return urllib.parse.quote(path) - - def get_status_code(self, record): - status_code = record.__dict__["status_code"] - try: - status_phrase = http.HTTPStatus(status_code).phrase - except ValueError: - status_phrase = "" - status_and_phrase = "%s %s" % (status_code, status_phrase) - - if self.use_colors: - - def default(code): - return status_and_phrase - - func = self.status_code_colours.get(status_code // 100, default) - return func(status_and_phrase) - return status_and_phrase - - def formatMessage(self, record): - recordcopy = copy(record) - scope = recordcopy.__dict__["scope"] - method = scope["method"] - path = self.get_path(scope) - full_path = self.get_full_path(scope) - client_addr = self.get_client_addr(scope) - status_code = self.get_status_code(recordcopy) - http_version = scope["http_version"] - request_line = "%s %s HTTP/%s" % (method, full_path, http_version) - if self.use_colors: - request_line = click.style(request_line, bold=True) - recordcopy.__dict__.update( - { - "method": method, - "path": path, - "full_path": full_path, - "client_addr": client_addr, - "request_line": request_line, - "status_code": status_code, - "http_version": http_version, - } - ) - return super().formatMessage(recordcopy) diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/__init__.py b/env/lib/python3.8/site-packages/uvicorn/loops/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 3159f7eb429f1ba7835bca6b88f7eaf9d4ccb7c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmWIL<>g`k0?X-#;z9Id5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_Uenx(7s(x{5 za#3nYeqO46dS*#{QEEYcv3_Y@rhY+Ua!E#NZepHpacWUnYLR|wUYUMQW|DqEWl2VU zp0S>VesN|=sxDAnc4B%eP*YiEa(+>seolUVL9u>(d}bcdym-BW%3B;Zx%nxjIjMFa J7kma{1^|o>H1_}i diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/asyncio.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/asyncio.cpython-38.pyc deleted file mode 100644 index 67650ad3bd4e1fe54de83042a230bcc5383fdfd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 633 zcmYjPOK#gR5FJuhEGu?^rk^_)Xu?G|El?Cii|mSQf}({tf+|jI+7c;{v;zalu6O9x zUiJb#K###~SH41leuhd6n8LhyZ)P|%g7k4T%7M23%GV_a}Bs$ljB=&jcRkY|bTHr1o9MsYl0q zn{*2@S#XLUZTefd1D|aMx3Fb*j97llwv2&3C4NlVgP4Rk{c;xv?J|PU|D?1uH*P!( ziCeocT%mQ!=tAjh6Vj%f8%s`Ua#>rK{@U0k98syqCJY?bSb1YzIJxTRJyLPMbZcEH z6CUkD7c12MgE4J5ap((-vZy<)@#a8}dC2ySLoZf*2m6?|{XG>k)1YuzS@cGum?~db zY>g93twdW^euhn{&m3BM5rKLoYV}35Yd9&j^6$|2WV8@+AMm(~RY8$TMc2Qf8dm5ji`Ea2z3x5L4am2k?Yq WA$#2zxvcRG{aWDSx5!xcB>w^beXK12 diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/auto.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/auto.cpython-38.pyc deleted file mode 100644 index 27c38c02556478ae3e62962f7e33960053abe93d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 508 zcmY+Bu};G<5J1mPD5a!jDJvsVhQ<;sAR&Z=7+~mv5YVLxvDHRR?8tT^710U)fp6e9 z_>8Pf%xp}YQ$)*IcjtTdozJ?PZnpy{$FJ|>Jp%CIf_0%7oS~Wk4F^tMU<90AL+B+) z{=~yw8}%I3T%makIN^}N0&YR>`(VkeqYntUg(ozlxwjw$p2#zjdyxG*$GyzYHx?8* zb({mf?WWq}|lt4yilH*VFfWn6Dx=7rMsLTjZ*yJeLoO3TPy zHPLSk?Y=hZ|36!%YxkSb(>}VovwEQ6Z=g4ke{(ifxnM>lT396oo1}KEMWGBUWy*>; zu~U)9a$tn6gl0lkEK46)F}G7C52GVyQY!{{Zx&AkCM}y}O_MAxt%{0yz2i3HRSP&H nFg-LtC<#c91k^3Pg=83##y9<~88?@@eUd9)X5!RU_(Fvr!-swr diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/uvloop.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/loops/__pycache__/uvloop.cpython-38.pyc deleted file mode 100644 index bc4cc67aae42c0bea17deec9046bd317f44e80ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352 zcmYjMu}TCn5KT7gxrm1#*!crntSe$+AtH#K90y{PCLBq?V0IId&B|gce#c$uZ}=J8 zTKNlB&fFH>z`S{HW->E*n$Hgi*xSdK@DRUI>{Qy#(l~w+btiPM+fG>LyztH% zIgGQ^qvS{TSb6}u+!j7b!1-JFy{fy$*WUOlwSFaEw5nd8wYJr{H5bjL9qQB@=|WrM ztOyF@nIFc(i3(Vr{0xu9e-j#zmn@(P3;`4WD<`%Gxv{uzoJv;TP*4$%Dzbw80VoJh AegFUf diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/asyncio.py b/env/lib/python3.8/site-packages/uvicorn/loops/asyncio.py deleted file mode 100644 index f2ac3f9a..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/loops/asyncio.py +++ /dev/null @@ -1,18 +0,0 @@ -import asyncio -import platform -import selectors -import sys - - -def asyncio_setup(): - if ( - sys.version_info.major >= 3 - and sys.version_info.minor >= 8 - and platform.system() == "Windows" - ): - selector = selectors.SelectSelector() - loop = asyncio.SelectorEventLoop(selector) - asyncio.set_event_loop(loop) - else: - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/auto.py b/env/lib/python3.8/site-packages/uvicorn/loops/auto.py deleted file mode 100644 index b9200749..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/loops/auto.py +++ /dev/null @@ -1,11 +0,0 @@ -def auto_loop_setup(): - try: - import uvloop # noqa - except ImportError: # pragma: no cover - from uvicorn.loops.asyncio import asyncio_setup as loop_setup - - loop_setup() - else: - from uvicorn.loops.uvloop import uvloop_setup - - uvloop_setup() diff --git a/env/lib/python3.8/site-packages/uvicorn/loops/uvloop.py b/env/lib/python3.8/site-packages/uvicorn/loops/uvloop.py deleted file mode 100644 index 8cd55c77..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/loops/uvloop.py +++ /dev/null @@ -1,7 +0,0 @@ -import asyncio - -import uvloop - - -def uvloop_setup(): - asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) diff --git a/env/lib/python3.8/site-packages/uvicorn/main.py b/env/lib/python3.8/site-packages/uvicorn/main.py deleted file mode 100644 index eaad7613..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/main.py +++ /dev/null @@ -1,385 +0,0 @@ -import logging -import platform -import ssl -import sys -import typing - -import click - -import uvicorn -from uvicorn._impl.asyncio import AsyncioServer, AsyncioServerState -from uvicorn.config import ( - HTTP_PROTOCOLS, - INTERFACES, - LIFESPAN, - LOG_LEVELS, - LOGGING_CONFIG, - LOOP_SETUPS, - SSL_PROTOCOL_VERSION, - WS_PROTOCOLS, - Config, -) -from uvicorn.supervisors import ChangeReload, Multiprocess - -LEVEL_CHOICES = click.Choice(LOG_LEVELS.keys()) -HTTP_CHOICES = click.Choice(HTTP_PROTOCOLS.keys()) -WS_CHOICES = click.Choice(WS_PROTOCOLS.keys()) -LIFESPAN_CHOICES = click.Choice(LIFESPAN.keys()) -LOOP_CHOICES = click.Choice([key for key in LOOP_SETUPS.keys() if key != "none"]) -INTERFACE_CHOICES = click.Choice(INTERFACES) - -logger = logging.getLogger("uvicorn.error") - -# Aliases for backwards compatibility. These used to be defined here. -Server = AsyncioServer -ServerState = AsyncioServerState - - -def print_version(ctx, param, value): - if not value or ctx.resilient_parsing: - return - click.echo( - "Running uvicorn %s with %s %s on %s" - % ( - uvicorn.__version__, - platform.python_implementation(), - platform.python_version(), - platform.system(), - ) - ) - ctx.exit() - - -@click.command() -@click.argument("app") -@click.option( - "--host", - type=str, - default="127.0.0.1", - help="Bind socket to this host.", - show_default=True, -) -@click.option( - "--port", - type=int, - default=8000, - help="Bind socket to this port.", - show_default=True, -) -@click.option("--uds", type=str, default=None, help="Bind to a UNIX domain socket.") -@click.option( - "--fd", type=int, default=None, help="Bind to socket from this file descriptor." -) -@click.option( - "--debug", is_flag=True, default=False, help="Enable debug mode.", hidden=True -) -@click.option("--reload", is_flag=True, default=False, help="Enable auto-reload.") -@click.option( - "--reload-dir", - "reload_dirs", - multiple=True, - help="Set reload directories explicitly, instead of using the current working" - " directory.", -) -@click.option( - "--reload-delay", - type=float, - default=0.25, - show_default=True, - help="Delay between previous and next check if application needs to be." - " Defaults to 0.25s.", -) -@click.option( - "--workers", - default=None, - type=int, - help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment" - " variable if available. Not valid with --reload.", -) -@click.option( - "--loop", - type=LOOP_CHOICES, - default="auto", - help="Event loop implementation.", - show_default=True, -) -@click.option( - "--http", - type=HTTP_CHOICES, - default="auto", - help="HTTP protocol implementation.", - show_default=True, -) -@click.option( - "--ws", - type=WS_CHOICES, - default="auto", - help="WebSocket protocol implementation.", - show_default=True, -) -@click.option( - "--lifespan", - type=LIFESPAN_CHOICES, - default="auto", - help="Lifespan implementation.", - show_default=True, -) -@click.option( - "--interface", - type=INTERFACE_CHOICES, - default="auto", - help="Select ASGI3, ASGI2, or WSGI as the application interface.", - show_default=True, -) -@click.option( - "--env-file", - type=click.Path(exists=True), - default=None, - help="Environment configuration file.", - show_default=True, -) -@click.option( - "--log-config", - type=click.Path(exists=True), - default=None, - help="Logging configuration file.", - show_default=True, -) -@click.option( - "--log-level", - type=LEVEL_CHOICES, - default=None, - help="Log level. [default: info]", - show_default=True, -) -@click.option( - "--access-log/--no-access-log", - is_flag=True, - default=True, - help="Enable/Disable access log.", -) -@click.option( - "--use-colors/--no-use-colors", - is_flag=True, - default=None, - help="Enable/Disable colorized logging.", -) -@click.option( - "--proxy-headers/--no-proxy-headers", - is_flag=True, - default=True, - help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to " - "populate remote address info.", -) -@click.option( - "--forwarded-allow-ips", - type=str, - default=None, - help="Comma seperated list of IPs to trust with proxy headers. Defaults to" - " the $FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'.", -) -@click.option( - "--root-path", - type=str, - default="", - help="Set the ASGI 'root_path' for applications submounted below a given URL path.", -) -@click.option( - "--limit-concurrency", - type=int, - default=None, - help="Maximum number of concurrent connections or tasks to allow, before issuing" - " HTTP 503 responses.", -) -@click.option( - "--backlog", - type=int, - default=2048, - help="Maximum number of connections to hold in backlog", -) -@click.option( - "--limit-max-requests", - type=int, - default=None, - help="Maximum number of requests to service before terminating the process.", -) -@click.option( - "--timeout-keep-alive", - type=int, - default=5, - help="Close Keep-Alive connections if no new data is received within this timeout.", - show_default=True, -) -@click.option( - "--ssl-keyfile", type=str, default=None, help="SSL key file", show_default=True -) -@click.option( - "--ssl-certfile", - type=str, - default=None, - help="SSL certificate file", - show_default=True, -) -@click.option( - "--ssl-keyfile-password", - type=str, - default=None, - help="SSL keyfile password", - show_default=True, -) -@click.option( - "--ssl-version", - type=int, - default=SSL_PROTOCOL_VERSION, - help="SSL version to use (see stdlib ssl module's)", - show_default=True, -) -@click.option( - "--ssl-cert-reqs", - type=int, - default=ssl.CERT_NONE, - help="Whether client certificate is required (see stdlib ssl module's)", - show_default=True, -) -@click.option( - "--ssl-ca-certs", - type=str, - default=None, - help="CA certificates file", - show_default=True, -) -@click.option( - "--ssl-ciphers", - type=str, - default="TLSv1", - help="Ciphers to use (see stdlib ssl module's)", - show_default=True, -) -@click.option( - "--header", - "headers", - multiple=True, - help="Specify custom default HTTP response headers as a Name:Value pair", -) -@click.option( - "--version", - is_flag=True, - callback=print_version, - expose_value=False, - is_eager=True, - help="Display the uvicorn version and exit.", -) -@click.option( - "--app-dir", - "app_dir", - default=".", - show_default=True, - help="Look for APP in the specified directory, by adding this to the PYTHONPATH." - " Defaults to the current working directory.", -) -def main( - app, - host: str, - port: int, - uds: str, - fd: int, - loop: str, - http: str, - ws: str, - lifespan: str, - interface: str, - debug: bool, - reload: bool, - reload_dirs: typing.List[str], - reload_delay: float, - workers: int, - env_file: str, - log_config: str, - log_level: str, - access_log: bool, - proxy_headers: bool, - forwarded_allow_ips: str, - root_path: str, - limit_concurrency: int, - backlog: int, - limit_max_requests: int, - timeout_keep_alive: int, - ssl_keyfile: str, - ssl_certfile: str, - ssl_keyfile_password: str, - ssl_version: int, - ssl_cert_reqs: int, - ssl_ca_certs: str, - ssl_ciphers: str, - headers: typing.List[str], - use_colors: bool, - app_dir: str, -): - sys.path.insert(0, app_dir) - - kwargs = { - "app": app, - "host": host, - "port": port, - "uds": uds, - "fd": fd, - "loop": loop, - "http": http, - "ws": ws, - "lifespan": lifespan, - "env_file": env_file, - "log_config": LOGGING_CONFIG if log_config is None else log_config, - "log_level": log_level, - "access_log": access_log, - "interface": interface, - "debug": debug, - "reload": reload, - "reload_dirs": reload_dirs if reload_dirs else None, - "reload_delay": reload_delay, - "workers": workers, - "proxy_headers": proxy_headers, - "forwarded_allow_ips": forwarded_allow_ips, - "root_path": root_path, - "limit_concurrency": limit_concurrency, - "backlog": backlog, - "limit_max_requests": limit_max_requests, - "timeout_keep_alive": timeout_keep_alive, - "ssl_keyfile": ssl_keyfile, - "ssl_certfile": ssl_certfile, - "ssl_keyfile_password": ssl_keyfile_password, - "ssl_version": ssl_version, - "ssl_cert_reqs": ssl_cert_reqs, - "ssl_ca_certs": ssl_ca_certs, - "ssl_ciphers": ssl_ciphers, - "headers": list([header.split(":", 1) for header in headers]), - "use_colors": use_colors, - } - run(**kwargs) - - -def run(app, **kwargs): - config = Config(app, **kwargs) - server = Server(config=config) - - if (config.reload or config.workers > 1) and not isinstance(app, str): - logger = logging.getLogger("uvicorn.error") - logger.warning( - "You must pass the application as an import string to enable 'reload' or " - "'workers'." - ) - sys.exit(1) - - if config.should_reload: - sock = config.bind_socket() - supervisor = ChangeReload(config, target=server.run, sockets=[sock]) - supervisor.run() - elif config.workers > 1: - sock = config.bind_socket() - supervisor = Multiprocess(config, target=server.run, sockets=[sock]) - supervisor.run() - else: - server.run() - - -if __name__ == "__main__": - main() diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/__init__.py b/env/lib/python3.8/site-packages/uvicorn/middleware/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 02a468c10802dfdbe469164930f743f1fafd716d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmYk0F%H5o3`J9k0U`Au46O$ikPzYoEQmP@jnzgpPL!lYJqc&v8XSX_Bd{^yOz@@u zEL;ATPi46ftj+BqbA4s}tKeqOjx&Z9N3kppcMJ+AwDW=KRxGL N>-5m$F2C_+i!Z8YHthfa diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/asgi2.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/asgi2.cpython-38.pyc deleted file mode 100644 index ad9a4a4ef5422cd7088df3145029876d150b1d86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmZutJ#Q2-5ViLsS)CFgQBffJEpnDZ0}?_(6d^^fInium8GE=h?0Oe_?@*$pO8x_F zDDQ7T#b4MqKOtSJ%K95aBV>DKpIQ zYs6JlFcZyL9&0@RDv>_%(O|ZY@gtK{OZbvUbm>FGR2{9AVvOwEz^Yt**Tj)gPlm zg@rwyHWz&+rFHncB&%WY&o7_+)7Nxcq{-$sQe4n{e<8v%q>kNSlRx;kq)WP}i?5>g%4ryeG15MjqgAcSQc4ns!3m%I z*X&p}%Tv-gRe_ZKM9Qi*tCH3SQhr&fa=h^wKIadJX!<)uzj}^D7(UE+77r)0oDX@Y RdJvCBUyVP#Cfyx^JpkatnL7Xg diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/debug.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/debug.cpython-38.pyc deleted file mode 100644 index e3a244d910bf90556eec486558208aa050276ac8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2748 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 diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/wsgi.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/middleware/__pycache__/wsgi.cpython-38.pyc deleted file mode 100644 index 7cf43d353dda2266d684ee086e18b400b5e54607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4294 zcmaJ^&vV#SOQiPcymq}4~)7&;SZ3utd(06nsdXa7dF|zT4dkE53NJ@(CfSSsvqJF zx9^IJJC^#JcvQmKOLvu@NDx)M}$m~><%h($%oy{^=0Wmjq) zY|2U$rwJ6kTED+sk@0?{lDLvQ+LmEDZqL?W%5-x6-uZ?@OhlB(7R7;UT6-WUdakdmE<#n$-x!rJm`({J2;P;ZT`-fb@V%Z+<0tunOMzV_FfYs-!Mt#j-3wJ+;y{_5IF zb7f)W^IrL}-i+plTlUVGQCGG7e7|1FOhj>~oA$;{Un-R--J3Fl-EKRL(k&$e(K~-K z(@{wX3-u<4>gbR-LjG}d1m$A-cxH8Ft(m!D zJCbqQ8egkFSZUV%yNio!nYV?#VX(|?2Wb@F=uL)6oI>qdTgIEP_~gP$qgih>{m<)- z`^}|ZdGtIz=*U)i^tAc)YCU&^e^tNY*D~(E;vZIvnJZ+N2$|WNGR>?g$-K`FQmL0$ zGFu;DTb+uen`VV>rz2J7DcNZUp{$N&1p}MR8)7AM9wp)+^M)`{6pN}%zIEaNo-OPL z?XGO$^OXXAr0{9_uS`{-^D3%sCA+ewWvFDD#Im*-r9SpbbgdglwN4PGz(){Y%S~Lv zF12>_sMa|E{NkJQpVV}e%4^Wu0dDcqeuRzU+HNF7TRskytQlW*4zh_ygnNJZogQ}A zpFyyK%PsEmGB4p?;zjP@j^DrCseDxCWt)0sd)7R6(RZy`%$4{Qn!18jLR#wdWn*v$ zO<#tPti=Tb>v@LfIC#&n9C*(qPRk}K)E*pv^h;vaGZaV5QCmRMZ$b2VpZP51+txOy zOYlF?*bxlNS&b@hjqe6e{Ktvf0f?%F%nmx8tOSgNUHBnRGjF4tc9qoGbkpE`HA&j_ zCo=4&iOPy{*sI!^qh)(TUB#A}H(by7E*J07e9`x#7>@HlrLS`!7%bYmaQ0C1BdySA zkQS~28jW9|>7PRMdCuKCmYz!4w>-tcw!!2$CVy%Z`}VEA{nT1UE?Ht65=XWhnM1%= zMXXSDvdOy|h)F>=b&Bh3f<9$U>P`|Ps?2Frl~fDrC%7rHD1khb(LUHn%UEQ^DAs9! z0Dr@A5#(*({{`OC6wnMnn0nKJb3OP&eE==^0j47S`+ipP{oO=#+te@n{$4j|=TFp! zP*pccRL%-Awt64p6EtJzA}={+CdAB{%f{#qn*JHYG5)x)kY#NF{NWA^3YW4j@?BAk zJ>xA`l*Bk@JmJBr6RL)n&$x?RWuYyg=|zYfhj0n=InoXDk=h}V*a?qmff5&b-X_VS znH>{^)spFt4-pIMKk-WL4p2~#c6Bxdl)`UX`Xf&C0(}sN;H*M@pRimafBEuMAL*zI zKem&kbLxF8sK7u3?+}RHNUBcmenPjwgW36%*^R}?A9Peb3qi;p{Yt}LZ|)4dPJm8M z7+n<7)Lx)z3)v5FW;uvaXxK>SaL&L2z^M-hp^rjBt)0?y0e*L+`7whojfT2=9}Gjq z?mGw+FSU;xWBUSv2Y!I`&`>%+jtv|X5j0;y*)mSW56Y0S-W=YV>cdZi;{f}LeFWca zmyaee%Q^KYkIoGcdPaBbwC-={>3P9W{CsD61r%P>rsq;2hG!_g2G+NrLn6M0x&(9l z3yo!CyNQxMWs`fRI54U5C4sFvqh@e3M4Nkvh$fpv>dL+DlcN=dV|I?xauoX`1~YEW z9LfUOqyYf(OOB^(99btwrJn|RhqAcghFi3X3%bNm{hS82Mv5#x4#035$YQ@Vdp|~f z;HL^X@ez_wwUh(tI-aQ;B;F=Lhf{YUT4g$yKg^lx9h$F`pxXF#yxqhcRS$X|f*~`} z&q15wllT$p9B`(^obMfb8o6rDqU=T4>3@-!Gf+ro99@J;YA?`q0|I_wYMvwtSi*sY zjKWavUM4Rg!mX!#M7MjSjdFP~#IC`EMM&dpFDGNGVf+VfHMX=n@QpE~LpIC`VOs{O zYUdU^F;)d%lAFRr9a&}*O;18Fi!wCj<|zwAJ9{?Xa?dr+5EUhOqUHrO{W}OlPW16y zKQsiy`~1kFd_1sFjXQ^hlmZ8}ex95A)*{1*!p1oQPg3X!@3}n;0r$uR69Ne#F$8n- z6|Wf7h6wNDi%d;lvW})H4GaPl2FrL!c(?wBcDB{~L_Y)iOOY@i=P$sFNi2^MYCj z8`8i*{fd_Hau}F(DXrzt=Fm)yH6rFIQ=VDhxsGd@Lhe5Z z6R&sa|C!-TspVirLXSbtLv%opCJ4+ww;$8L!fiqh(jB4a7!jabJSl9ugowTJNQ=<) z9Q0}e<&2I&joau=pS3qJMRR2DV+K)o@Fi6%_X5qrawct2jGfq9eMv)#w%okK1ZN0` z%!TON>c%^-Taviw_h@;rfoNP_B66{&d2jlx<%mhEyiqMGs@Bv;B&fzXRkj#XGtQxP zPwiEqp^0uPER2CEB^G(HT)a>mFU^>O14|ozpFSy9=ZDp*`Vp-_d05SnxI*H6613o( acFKyk@-pi-#iXWxCfJUCcJapK_

    500 Server Error

    %s
    " - % exc_html - ) - response = HTMLResponse(content, status_code=500) - else: - content = traceback.format_exc() - response = PlainTextResponse(content, status_code=500) - - await response(scope, receive, send) - raise exc from None diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py b/env/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py deleted file mode 100644 index a05b5c13..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/middleware/message_logger.py +++ /dev/null @@ -1,68 +0,0 @@ -import logging - -PLACEHOLDER_FORMAT = { - "body": "<{length} bytes>", - "bytes": "<{length} bytes>", - "text": "<{length} chars>", - "headers": "<...>", -} -TRACE_LOG_LEVEL = 5 - - -def message_with_placeholders(message): - """ - Return an ASGI message, with any body-type content omitted and replaced - with a placeholder. - """ - new_message = message.copy() - for attr in PLACEHOLDER_FORMAT.keys(): - if message.get(attr) is not None: - content = message[attr] - placeholder = PLACEHOLDER_FORMAT[attr].format(length=len(content)) - new_message[attr] = placeholder - return new_message - - -class MessageLoggerMiddleware: - def __init__(self, app): - self.task_counter = 0 - self.app = app - self.logger = logging.getLogger("uvicorn.asgi") - - def trace(message, *args, **kwargs): - self.logger.log(TRACE_LOG_LEVEL, message, *args, **kwargs) - - self.logger.trace = trace - - async def __call__(self, scope, receive, send): - self.task_counter += 1 - - task_counter = self.task_counter - client = scope.get("client") - prefix = "%s:%d - ASGI" % (client[0], client[1]) if client else "ASGI" - - async def inner_receive(): - message = await receive() - logged_message = message_with_placeholders(message) - log_text = "%s [%d] Receive %s" - self.logger.trace(log_text, prefix, task_counter, logged_message) - return message - - async def inner_send(message): - logged_message = message_with_placeholders(message) - log_text = "%s [%d] Send %s" - self.logger.trace(log_text, prefix, task_counter, logged_message) - await send(message) - - logged_scope = message_with_placeholders(scope) - log_text = "%s [%d] Started scope=%s" - self.logger.trace(log_text, prefix, task_counter, logged_scope) - try: - await self.app(scope, inner_receive, inner_send) - except BaseException as exc: - log_text = "%s [%d] Raised exception" - self.logger.trace(log_text, prefix, task_counter) - raise exc from None - else: - log_text = "%s [%d] Completed" - self.logger.trace(log_text, prefix, task_counter) diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py b/env/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py deleted file mode 100644 index 05f4f70e..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -This middleware can be used when a known proxy is fronting the application, -and is trusted to be properly setting the `X-Forwarded-Proto` and -`X-Forwarded-For` headers with the connecting client information. - -Modifies the `client` and `scheme` information so that they reference -the connecting client, rather that the connecting proxy. - -https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies -""" - - -class ProxyHeadersMiddleware: - def __init__(self, app, trusted_hosts="127.0.0.1"): - self.app = app - if isinstance(trusted_hosts, str): - self.trusted_hosts = [item.strip() for item in trusted_hosts.split(",")] - else: - self.trusted_hosts = trusted_hosts - self.always_trust = "*" in self.trusted_hosts - - async def __call__(self, scope, receive, send): - if scope["type"] in ("http", "websocket"): - client_addr = scope.get("client") - client_host = client_addr[0] if client_addr else None - - if self.always_trust or client_host in self.trusted_hosts: - headers = dict(scope["headers"]) - - if b"x-forwarded-proto" in headers: - # Determine if the incoming request was http or https based on - # the X-Forwarded-Proto header. - x_forwarded_proto = headers[b"x-forwarded-proto"].decode("latin1") - scope["scheme"] = x_forwarded_proto.strip() - - if b"x-forwarded-for" in headers: - # Determine the client address from the last trusted IP in the - # X-Forwarded-For header. We've lost the connecting client's port - # information by now, so only include the host. - x_forwarded_for = headers[b"x-forwarded-for"].decode("latin1") - host = x_forwarded_for.split(",")[-1].strip() - port = 0 - scope["client"] = (host, port) - - return await self.app(scope, receive, send) diff --git a/env/lib/python3.8/site-packages/uvicorn/middleware/wsgi.py b/env/lib/python3.8/site-packages/uvicorn/middleware/wsgi.py deleted file mode 100644 index e5346ddc..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/middleware/wsgi.py +++ /dev/null @@ -1,141 +0,0 @@ -import asyncio -import concurrent.futures -import io -import sys - - -def build_environ(scope, message, body): - """ - Builds a scope and request message into a WSGI environ object. - """ - environ = { - "REQUEST_METHOD": scope["method"], - "SCRIPT_NAME": "", - "PATH_INFO": scope["path"], - "QUERY_STRING": scope["query_string"].decode("ascii"), - "SERVER_PROTOCOL": "HTTP/%s" % scope["http_version"], - "wsgi.version": (1, 0), - "wsgi.url_scheme": scope.get("scheme", "http"), - "wsgi.input": io.BytesIO(body), - "wsgi.errors": sys.stdout, - "wsgi.multithread": True, - "wsgi.multiprocess": True, - "wsgi.run_once": False, - } - - # Get server name and port - required in WSGI, not in ASGI - server = scope.get("server") - if server is None: - server = ("localhost", 80) - environ["SERVER_NAME"] = server[0] - environ["SERVER_PORT"] = server[1] - - # Get client IP address - client = scope.get("client") - if client is not None: - environ["REMOTE_ADDR"] = client[0] - - # Go through headers and make them into environ entries - for name, value in scope.get("headers", []): - name = name.decode("latin1") - if name == "content-length": - corrected_name = "CONTENT_LENGTH" - elif name == "content-type": - corrected_name = "CONTENT_TYPE" - else: - corrected_name = "HTTP_%s" % name.upper().replace("-", "_") - # HTTPbis say only ASCII chars are allowed in headers, but we latin1 - # just in case - value = value.decode("latin1") - if corrected_name in environ: - value = environ[corrected_name] + "," + value - environ[corrected_name] = value - return environ - - -class WSGIMiddleware: - def __init__(self, app, workers=10): - self.app = app - self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=workers) - - async def __call__(self, scope, receive, send): - assert scope["type"] == "http" - instance = WSGIResponder(self.app, self.executor, scope) - await instance(receive, send) - - -class WSGIResponder: - def __init__(self, app, executor, scope): - self.app = app - self.executor = executor - self.scope = scope - self.status = None - self.response_headers = None - self.send_event = asyncio.Event() - self.send_queue = [] - self.loop = None - self.response_started = False - self.exc_info = None - - async def __call__(self, receive, send): - message = await receive() - body = message.get("body", b"") - more_body = message.get("more_body", False) - while more_body: - body_message = await receive() - body += body_message.get("body", b"") - more_body = body_message.get("more_body", False) - environ = build_environ(self.scope, message, body) - self.loop = asyncio.get_event_loop() - wsgi = self.loop.run_in_executor( - self.executor, self.wsgi, environ, self.start_response - ) - sender = self.loop.create_task(self.sender(send)) - try: - await asyncio.wait_for(wsgi, None) - finally: - self.send_queue.append(None) - self.send_event.set() - await asyncio.wait_for(sender, None) - if self.exc_info is not None: - raise self.exc_info[0].with_traceback(self.exc_info[1], self.exc_info[2]) - - async def sender(self, send): - while True: - if self.send_queue: - message = self.send_queue.pop(0) - if message is None: - return - await send(message) - else: - await self.send_event.wait() - self.send_event.clear() - - def start_response(self, status, response_headers, exc_info=None): - self.exc_info = exc_info - if not self.response_started: - self.response_started = True - status_code, _ = status.split(" ", 1) - status_code = int(status_code) - headers = [ - (name.encode("ascii"), value.encode("ascii")) - for name, value in response_headers - ] - self.send_queue.append( - { - "type": "http.response.start", - "status": status_code, - "headers": headers, - } - ) - self.loop.call_soon_threadsafe(self.send_event.set) - - def wsgi(self, environ, start_response): - for chunk in self.app(environ, start_response): - self.send_queue.append( - {"type": "http.response.body", "body": chunk, "more_body": True} - ) - self.loop.call_soon_threadsafe(self.send_event.set) - - self.send_queue.append({"type": "http.response.body", "body": b""}) - self.loop.call_soon_threadsafe(self.send_event.set) diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/__init__.py b/env/lib/python3.8/site-packages/uvicorn/protocols/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index b5a9dd4accd1d02d2e984a0e86eac5fabf332000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmYk0K?=e^3`M8lLWCZ~MVo~i1rbl+MqCed8tmXS8D^%1p2RbF4Ugg0Be-*AW~Cqg z3kmrlr?Olq(dPEhxxO;~RYtcNOyZhmV7fdxVH4U}8eJ*rWq`jxdk~ z-NP~0u#&xNb3qA>)^H&3ffE~c5wx}>H+Ai&=X~39 MJ2>3sFWzGH1$K2dvj6}9 diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 90d90cfae04a870a200eb6e143b67648f605ff8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1574 zcmaJ>OK%)S5bo}I?CkmxFyN5z5(pzkA{it&Koprs2#J$9tPo)@qsesJZgzHhQr&B? zvp(4e{sFgWms|b@Kclal{1>=DRd291c9a=)b@l7(n(wQcA2&7z44<$6_^bRrW$bSn ztUdw<53t!U(MTqF!$wRB8J)8cm$6K+7c!MS>?4`UKK8L3$TjQ}$%iaozrd4hujbS} zeTdJ%d1 zq7{<;#D*+pE*%fxA!qddjL{C+!zFTz$cPef*$I1bH$^{vpbxJ{7P1FSumG}MTfpVq#%|TV_cHj6l9RI(^546>-byZs{pSWq) zC?8n|KGLo8y&s0(0T}RcqpkB%quOVY?;}!cI|FXCw!D3b8x#6723vUTKe{+H6IEDM zgL0--#esGusLt48+UlaKYImq6ReQ%OI8sok_NZv|qoO-@ho=4F?pKA?PTj$M@;29U#KINNHCIzrvoL?3AJP4dV7x>)uE(Jb+6%GmvBw|n(C_{ZljFY;M z;4sesD})6}FBd3_p-+bD2-e7Kkl7@2gA7TuG;g4{%#g;^RTBt&3+L=>XqE(K;u9n? zPH$B&F@LeMz}y5njrskSAa_z;&Y zeLLfD8|@3X(mb&d1f$he!R(e4SRc`hZ)3IPG1f@kXocy_PLdsaZ%5|bN0>7hO=4@) zDR>7VuEr6vYI!h_vV(gpQA?!6_`(P1Uki)m2x0A_No8xT^VFwPXt0!g(p6xwsvl3WGT=Qrp6(l%RL-YT)kdmZ!238o+9uTUSB+*B z`6?y1snA}&^)rOAlvRwUeCyvh%8((!*3p9;XY&+3#xB$zP!JcKEfJ_ddv8)4niZD0} zzB1fmU%4V;7%>345juMYKXFTLRjwgg#zOWkRf7^5t)bw+2VyeRMQE8lXlS5Z+B?~UhDkCq%Bf6o zNOy9JDWuF1`Ms{qn9WZk(DS{Zj`j52h;nwOa}GSpO!UGPN}j~0#Fmcrp>LK>8Hkql$=W_??2{Dy#(Gh=214Z(XXo%M$VLDj Mj_@{)ytWs4-}hI3l>h($ diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/h11_impl.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/h11_impl.cpython-38.pyc deleted file mode 100644 index 694bf0d789c15adba6aeae8a71a3c71f5c14b7bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12876 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 diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/httptools_impl.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/http/__pycache__/httptools_impl.cpython-38.pyc deleted file mode 100644 index 0caa33e1120f16ca532175c7602fa29fe04315f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13959 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 i)qu1>O4b1vC~w1y09`ZbIF@4= self.limit_concurrency - or len(self.tasks) >= self.limit_concurrency - ): - app = service_unavailable - message = "Exceeded concurrency limit." - self.logger.warning(message) - else: - app = self.app - - self.cycle = RequestResponseCycle( - scope=self.scope, - conn=self.conn, - transport=self.transport, - flow=self.flow, - logger=self.logger, - access_logger=self.access_logger, - access_log=self.access_log, - default_headers=self.default_headers, - message_event=asyncio.Event(), - on_response=self.on_response_complete, - ) - task = self.loop.create_task(self.cycle.run_asgi(app)) - task.add_done_callback(self.tasks.discard) - self.tasks.add(task) - - elif event_type is h11.Data: - if self.conn.our_state is h11.DONE: - continue - self.cycle.body += event.data - if len(self.cycle.body) > HIGH_WATER_LIMIT: - self.flow.pause_reading() - self.cycle.message_event.set() - - elif event_type is h11.EndOfMessage: - if self.conn.our_state is h11.DONE: - self.transport.resume_reading() - self.conn.start_next_cycle() - continue - self.cycle.more_body = False - self.cycle.message_event.set() - - def handle_upgrade(self, event): - upgrade_value = None - for name, value in self.headers: - if name == b"upgrade": - upgrade_value = value.lower() - - if upgrade_value != b"websocket" or self.ws_protocol_class is None: - msg = "Unsupported upgrade request." - self.logger.warning(msg) - reason = STATUS_PHRASES[400] - headers = [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ] - event = h11.Response(status_code=400, headers=headers, reason=reason) - output = self.conn.send(event) - self.transport.write(output) - event = h11.Data(data=b"Unsupported upgrade request.") - output = self.conn.send(event) - self.transport.write(output) - event = h11.EndOfMessage() - output = self.conn.send(event) - self.transport.write(output) - self.transport.close() - return - - self.connections.discard(self) - output = [event.method, b" ", event.target, b" HTTP/1.1\r\n"] - for name, value in self.headers: - output += [name, b": ", value, b"\r\n"] - output.append(b"\r\n") - protocol = self.ws_protocol_class( - config=self.config, server_state=self.server_state - ) - protocol.connection_made(self.transport) - protocol.data_received(b"".join(output)) - self.transport.set_protocol(protocol) - - def on_response_complete(self): - self.server_state.total_requests += 1 - - if self.transport.is_closing(): - return - - # Set a short Keep-Alive timeout. - self._unset_keepalive_if_required() - - self.timeout_keep_alive_task = self.loop.call_later( - self.timeout_keep_alive, self.timeout_keep_alive_handler - ) - - # Unpause data reads if needed. - self.flow.resume_reading() - - # Unblock any pipelined events. - if self.conn.our_state is h11.DONE and self.conn.their_state is h11.DONE: - self.conn.start_next_cycle() - self.handle_events() - - def shutdown(self): - """ - Called by the server to commence a graceful shutdown. - """ - if self.cycle is None or self.cycle.response_complete: - event = h11.ConnectionClosed() - self.conn.send(event) - self.transport.close() - else: - self.cycle.keep_alive = False - - def pause_writing(self): - """ - Called by the transport when the write buffer exceeds the high water mark. - """ - self.flow.pause_writing() - - def resume_writing(self): - """ - Called by the transport when the write buffer drops below the low water mark. - """ - self.flow.resume_writing() - - def timeout_keep_alive_handler(self): - """ - Called on a keep-alive connection if no new data is received after a short - delay. - """ - if not self.transport.is_closing(): - event = h11.ConnectionClosed() - self.conn.send(event) - self.transport.close() - - -class RequestResponseCycle: - def __init__( - self, - scope, - conn, - transport, - flow, - logger, - access_logger, - access_log, - default_headers, - message_event, - on_response, - ): - self.scope = scope - self.conn = conn - self.transport = transport - self.flow = flow - self.logger = logger - self.access_logger = access_logger - self.access_log = access_log - self.default_headers = default_headers - self.message_event = message_event - self.on_response = on_response - - # Connection state - self.disconnected = False - self.keep_alive = True - self.waiting_for_100_continue = conn.they_are_waiting_for_100_continue - - # Request state - self.body = b"" - self.more_body = True - - # Response state - self.response_started = False - self.response_complete = False - - # ASGI exception wrapper - async def run_asgi(self, app): - try: - result = await app(self.scope, self.receive, self.send) - except BaseException as exc: - msg = "Exception in ASGI application\n" - self.logger.error(msg, exc_info=exc) - if not self.response_started: - await self.send_500_response() - else: - self.transport.close() - else: - if result is not None: - msg = "ASGI callable should return None, but returned '%s'." - self.logger.error(msg, result) - self.transport.close() - elif not self.response_started and not self.disconnected: - msg = "ASGI callable returned without starting response." - self.logger.error(msg) - await self.send_500_response() - elif not self.response_complete and not self.disconnected: - msg = "ASGI callable returned without completing response." - self.logger.error(msg) - self.transport.close() - finally: - self.on_response = None - - async def send_500_response(self): - await self.send( - { - "type": "http.response.start", - "status": 500, - "headers": [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ], - } - ) - await self.send( - {"type": "http.response.body", "body": b"Internal Server Error"} - ) - - # ASGI interface - async def send(self, message): - message_type = message["type"] - - if self.flow.write_paused and not self.disconnected: - await self.flow.drain() - - if self.disconnected: - return - - if not self.response_started: - # Sending response status line and headers - if message_type != "http.response.start": - msg = "Expected ASGI message 'http.response.start', but got '%s'." - raise RuntimeError(msg % message_type) - - self.response_started = True - self.waiting_for_100_continue = False - - status_code = message["status"] - headers = self.default_headers + message.get("headers", []) - - if self.access_log: - self.access_logger.info( - '%s - "%s %s HTTP/%s" %d', - get_client_addr(self.scope), - self.scope["method"], - get_path_with_query_string(self.scope), - self.scope["http_version"], - status_code, - extra={"status_code": status_code, "scope": self.scope}, - ) - - # Write response status line and headers - reason = STATUS_PHRASES[status_code] - event = h11.Response( - status_code=status_code, headers=headers, reason=reason - ) - output = self.conn.send(event) - self.transport.write(output) - - elif not self.response_complete: - # Sending response body - if message_type != "http.response.body": - msg = "Expected ASGI message 'http.response.body', but got '%s'." - raise RuntimeError(msg % message_type) - - body = message.get("body", b"") - more_body = message.get("more_body", False) - - # Write response body - if self.scope["method"] == "HEAD": - event = h11.Data(data=b"") - else: - event = h11.Data(data=body) - output = self.conn.send(event) - self.transport.write(output) - - # Handle response completion - if not more_body: - self.response_complete = True - self.message_event.set() - event = h11.EndOfMessage() - output = self.conn.send(event) - self.transport.write(output) - - else: - # Response already sent - msg = "Unexpected ASGI message '%s' sent, after response already completed." - raise RuntimeError(msg % message_type) - - if self.response_complete: - if self.conn.our_state is h11.MUST_CLOSE or not self.keep_alive: - event = h11.ConnectionClosed() - self.conn.send(event) - self.transport.close() - self.on_response() - - async def receive(self): - if self.waiting_for_100_continue and not self.transport.is_closing(): - event = h11.InformationalResponse( - status_code=100, headers=[], reason="Continue" - ) - output = self.conn.send(event) - self.transport.write(output) - self.waiting_for_100_continue = False - - if not self.disconnected and not self.response_complete: - self.flow.resume_reading() - await self.message_event.wait() - self.message_event.clear() - - if self.disconnected or self.response_complete: - message = {"type": "http.disconnect"} - else: - message = { - "type": "http.request", - "body": self.body, - "more_body": self.more_body, - } - self.body = b"" - - return message diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py b/env/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py deleted file mode 100644 index 924e131c..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py +++ /dev/null @@ -1,563 +0,0 @@ -import asyncio -import http -import logging -import re -import urllib - -import httptools - -from uvicorn.protocols.utils import ( - get_client_addr, - get_local_addr, - get_path_with_query_string, - get_remote_addr, - is_ssl, -) - -HEADER_RE = re.compile(b'[\x00-\x1F\x7F()<>@,;:[]={} \t\\"]') -HEADER_VALUE_RE = re.compile(b"[\x00-\x1F\x7F]") - - -def _get_status_line(status_code): - try: - phrase = http.HTTPStatus(status_code).phrase.encode() - except ValueError: - phrase = b"" - return b"".join([b"HTTP/1.1 ", str(status_code).encode(), b" ", phrase, b"\r\n"]) - - -STATUS_LINE = { - status_code: _get_status_line(status_code) for status_code in range(100, 600) -} - -HIGH_WATER_LIMIT = 65536 - -TRACE_LOG_LEVEL = 5 - - -class FlowControl: - def __init__(self, transport): - self._transport = transport - self.read_paused = False - self.write_paused = False - self._is_writable_event = asyncio.Event() - self._is_writable_event.set() - - async def drain(self): - await self._is_writable_event.wait() - - def pause_reading(self): - if not self.read_paused: - self.read_paused = True - self._transport.pause_reading() - - def resume_reading(self): - if self.read_paused: - self.read_paused = False - self._transport.resume_reading() - - def pause_writing(self): - if not self.write_paused: - self.write_paused = True - self._is_writable_event.clear() - - def resume_writing(self): - if self.write_paused: - self.write_paused = False - self._is_writable_event.set() - - -async def service_unavailable(scope, receive, send): - await send( - { - "type": "http.response.start", - "status": 503, - "headers": [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ], - } - ) - await send({"type": "http.response.body", "body": b"Service Unavailable"}) - - -class HttpToolsProtocol(asyncio.Protocol): - def __init__(self, config, server_state, _loop=None): - if not config.loaded: - config.load() - - self.config = config - self.app = config.loaded_app - self.loop = _loop or asyncio.get_event_loop() - self.logger = logging.getLogger("uvicorn.error") - self.access_logger = logging.getLogger("uvicorn.access") - self.access_log = self.access_logger.hasHandlers() - self.parser = httptools.HttpRequestParser(self) - self.ws_protocol_class = config.ws_protocol_class - self.root_path = config.root_path - self.limit_concurrency = config.limit_concurrency - - # Timeouts - self.timeout_keep_alive_task = None - self.timeout_keep_alive = config.timeout_keep_alive - - # Global state - self.server_state = server_state - self.connections = server_state.connections - self.tasks = server_state.tasks - self.default_headers = server_state.default_headers - - # Per-connection state - self.transport = None - self.flow = None - self.server = None - self.client = None - self.scheme = None - self.pipeline = [] - - # Per-request state - self.url = None - self.scope = None - self.headers = None - self.expect_100_continue = False - self.cycle = None - - # Protocol interface - def connection_made(self, transport): - self.connections.add(self) - - self.transport = transport - self.flow = FlowControl(transport) - self.server = get_local_addr(transport) - self.client = get_remote_addr(transport) - self.scheme = "https" if is_ssl(transport) else "http" - - if self.logger.level <= TRACE_LOG_LEVEL: - prefix = "%s:%d - " % tuple(self.client) if self.client else "" - self.logger.log(TRACE_LOG_LEVEL, "%sConnection made", prefix) - - def connection_lost(self, exc): - self.connections.discard(self) - - if self.logger.level <= TRACE_LOG_LEVEL: - prefix = "%s:%d - " % tuple(self.client) if self.client else "" - self.logger.log(TRACE_LOG_LEVEL, "%sConnection lost", prefix) - - if self.cycle and not self.cycle.response_complete: - self.cycle.disconnected = True - if self.cycle is not None: - self.cycle.message_event.set() - if self.flow is not None: - self.flow.resume_writing() - - def eof_received(self): - pass - - def _unset_keepalive_if_required(self): - if self.timeout_keep_alive_task is not None: - self.timeout_keep_alive_task.cancel() - self.timeout_keep_alive_task = None - - def data_received(self, data): - self._unset_keepalive_if_required() - - try: - self.parser.feed_data(data) - except httptools.HttpParserError: - msg = "Invalid HTTP request received." - self.logger.warning(msg) - self.transport.close() - except httptools.HttpParserUpgrade: - self.handle_upgrade() - - def handle_upgrade(self): - upgrade_value = None - for name, value in self.headers: - if name == b"upgrade": - upgrade_value = value.lower() - - if upgrade_value != b"websocket" or self.ws_protocol_class is None: - msg = "Unsupported upgrade request." - self.logger.warning(msg) - content = [STATUS_LINE[400]] - for name, value in self.default_headers: - content.extend([name, b": ", value, b"\r\n"]) - content.extend( - [ - b"content-type: text/plain; charset=utf-8\r\n", - b"content-length: " + str(len(msg)).encode("ascii") + b"\r\n", - b"connection: close\r\n", - b"\r\n", - msg.encode("ascii"), - ] - ) - self.transport.write(b"".join(content)) - self.transport.close() - return - - self.connections.discard(self) - method = self.scope["method"].encode() - output = [method, b" ", self.url, b" HTTP/1.1\r\n"] - for name, value in self.scope["headers"]: - output += [name, b": ", value, b"\r\n"] - output.append(b"\r\n") - protocol = self.ws_protocol_class( - config=self.config, server_state=self.server_state - ) - protocol.connection_made(self.transport) - protocol.data_received(b"".join(output)) - self.transport.set_protocol(protocol) - - # Parser callbacks - def on_url(self, url): - method = self.parser.get_method() - parsed_url = httptools.parse_url(url) - raw_path = parsed_url.path - path = raw_path.decode("ascii") - if "%" in path: - path = urllib.parse.unquote(path) - self.url = url - self.expect_100_continue = False - self.headers = [] - self.scope = { - "type": "http", - "asgi": {"version": self.config.asgi_version, "spec_version": "2.1"}, - "http_version": "1.1", - "server": self.server, - "client": self.client, - "scheme": self.scheme, - "method": method.decode("ascii"), - "root_path": self.root_path, - "path": path, - "raw_path": raw_path, - "query_string": parsed_url.query if parsed_url.query else b"", - "headers": self.headers, - } - - def on_header(self, name: bytes, value: bytes): - name = name.lower() - if name == b"expect" and value.lower() == b"100-continue": - self.expect_100_continue = True - self.headers.append((name, value)) - - def on_headers_complete(self): - http_version = self.parser.get_http_version() - if http_version != "1.1": - self.scope["http_version"] = http_version - if self.parser.should_upgrade(): - return - - # Handle 503 responses when 'limit_concurrency' is exceeded. - if self.limit_concurrency is not None and ( - len(self.connections) >= self.limit_concurrency - or len(self.tasks) >= self.limit_concurrency - ): - app = service_unavailable - message = "Exceeded concurrency limit." - self.logger.warning(message) - else: - app = self.app - - existing_cycle = self.cycle - self.cycle = RequestResponseCycle( - scope=self.scope, - transport=self.transport, - flow=self.flow, - logger=self.logger, - access_logger=self.access_logger, - access_log=self.access_log, - default_headers=self.default_headers, - message_event=asyncio.Event(), - expect_100_continue=self.expect_100_continue, - keep_alive=http_version != "1.0", - on_response=self.on_response_complete, - ) - if existing_cycle is None or existing_cycle.response_complete: - # Standard case - start processing the request. - task = self.loop.create_task(self.cycle.run_asgi(app)) - task.add_done_callback(self.tasks.discard) - self.tasks.add(task) - else: - # Pipelined HTTP requests need to be queued up. - self.flow.pause_reading() - self.pipeline.insert(0, (self.cycle, app)) - - def on_body(self, body: bytes): - if self.parser.should_upgrade() or self.cycle.response_complete: - return - self.cycle.body += body - if len(self.cycle.body) > HIGH_WATER_LIMIT: - self.flow.pause_reading() - self.cycle.message_event.set() - - def on_message_complete(self): - if self.parser.should_upgrade() or self.cycle.response_complete: - return - self.cycle.more_body = False - self.cycle.message_event.set() - - def on_response_complete(self): - # Callback for pipelined HTTP requests to be started. - self.server_state.total_requests += 1 - - if self.transport.is_closing(): - return - - # Set a short Keep-Alive timeout. - self._unset_keepalive_if_required() - - self.timeout_keep_alive_task = self.loop.call_later( - self.timeout_keep_alive, self.timeout_keep_alive_handler - ) - - # Unpause data reads if needed. - self.flow.resume_reading() - - # Unblock any pipelined events. - if self.pipeline: - cycle, app = self.pipeline.pop() - task = self.loop.create_task(cycle.run_asgi(app)) - task.add_done_callback(self.tasks.discard) - self.tasks.add(task) - - def shutdown(self): - """ - Called by the server to commence a graceful shutdown. - """ - if self.cycle is None or self.cycle.response_complete: - self.transport.close() - else: - self.cycle.keep_alive = False - - def pause_writing(self): - """ - Called by the transport when the write buffer exceeds the high water mark. - """ - self.flow.pause_writing() - - def resume_writing(self): - """ - Called by the transport when the write buffer drops below the low water mark. - """ - self.flow.resume_writing() - - def timeout_keep_alive_handler(self): - """ - Called on a keep-alive connection if no new data is received after a short - delay. - """ - if not self.transport.is_closing(): - self.transport.close() - - -class RequestResponseCycle: - def __init__( - self, - scope, - transport, - flow, - logger, - access_logger, - access_log, - default_headers, - message_event, - expect_100_continue, - keep_alive, - on_response, - ): - self.scope = scope - self.transport = transport - self.flow = flow - self.logger = logger - self.access_logger = access_logger - self.access_log = access_log - self.default_headers = default_headers - self.message_event = message_event - self.on_response = on_response - - # Connection state - self.disconnected = False - self.keep_alive = keep_alive - self.waiting_for_100_continue = expect_100_continue - - # Request state - self.body = b"" - self.more_body = True - - # Response state - self.response_started = False - self.response_complete = False - self.chunked_encoding = None - self.expected_content_length = 0 - - # ASGI exception wrapper - async def run_asgi(self, app): - try: - result = await app(self.scope, self.receive, self.send) - except BaseException as exc: - msg = "Exception in ASGI application\n" - self.logger.error(msg, exc_info=exc) - if not self.response_started: - await self.send_500_response() - else: - self.transport.close() - else: - if result is not None: - msg = "ASGI callable should return None, but returned '%s'." - self.logger.error(msg, result) - self.transport.close() - elif not self.response_started and not self.disconnected: - msg = "ASGI callable returned without starting response." - self.logger.error(msg) - await self.send_500_response() - elif not self.response_complete and not self.disconnected: - msg = "ASGI callable returned without completing response." - self.logger.error(msg) - self.transport.close() - finally: - self.on_response = None - - async def send_500_response(self): - await self.send( - { - "type": "http.response.start", - "status": 500, - "headers": [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ], - } - ) - await self.send( - {"type": "http.response.body", "body": b"Internal Server Error"} - ) - - # ASGI interface - async def send(self, message): - message_type = message["type"] - - if self.flow.write_paused and not self.disconnected: - await self.flow.drain() - - if self.disconnected: - return - - if not self.response_started: - # Sending response status line and headers - if message_type != "http.response.start": - msg = "Expected ASGI message 'http.response.start', but got '%s'." - raise RuntimeError(msg % message_type) - - self.response_started = True - self.waiting_for_100_continue = False - - status_code = message["status"] - headers = self.default_headers + list(message.get("headers", [])) - - if self.access_log: - self.access_logger.info( - '%s - "%s %s HTTP/%s" %d', - get_client_addr(self.scope), - self.scope["method"], - get_path_with_query_string(self.scope), - self.scope["http_version"], - status_code, - extra={"status_code": status_code, "scope": self.scope}, - ) - - # Write response status line and headers - content = [STATUS_LINE[status_code]] - - for name, value in headers: - if HEADER_RE.search(name): - raise RuntimeError("Invalid HTTP header name.") - if HEADER_VALUE_RE.search(value): - raise RuntimeError("Invalid HTTP header value.") - - name = name.lower() - if name == b"content-length" and self.chunked_encoding is None: - self.expected_content_length = int(value.decode()) - self.chunked_encoding = False - elif name == b"transfer-encoding" and value.lower() == b"chunked": - self.expected_content_length = 0 - self.chunked_encoding = True - elif name == b"connection" and value.lower() == b"close": - self.keep_alive = False - content.extend([name, b": ", value, b"\r\n"]) - - if ( - self.chunked_encoding is None - and self.scope["method"] != "HEAD" - and status_code not in (204, 304) - ): - # Neither content-length nor transfer-encoding specified - self.chunked_encoding = True - content.append(b"transfer-encoding: chunked\r\n") - - content.append(b"\r\n") - self.transport.write(b"".join(content)) - - elif not self.response_complete: - # Sending response body - if message_type != "http.response.body": - msg = "Expected ASGI message 'http.response.body', but got '%s'." - raise RuntimeError(msg % message_type) - - body = message.get("body", b"") - more_body = message.get("more_body", False) - - # Write response body - if self.scope["method"] == "HEAD": - self.expected_content_length = 0 - elif self.chunked_encoding: - if body: - content = [b"%x\r\n" % len(body), body, b"\r\n"] - else: - content = [] - if not more_body: - content.append(b"0\r\n\r\n") - self.transport.write(b"".join(content)) - else: - num_bytes = len(body) - if num_bytes > self.expected_content_length: - raise RuntimeError("Response content longer than Content-Length") - else: - self.expected_content_length -= num_bytes - self.transport.write(body) - - # Handle response completion - if not more_body: - if self.expected_content_length != 0: - raise RuntimeError("Response content shorter than Content-Length") - self.response_complete = True - self.message_event.set() - if not self.keep_alive: - self.transport.close() - self.on_response() - - else: - # Response already sent - msg = "Unexpected ASGI message '%s' sent, after response already completed." - raise RuntimeError(msg % message_type) - - async def receive(self): - if self.waiting_for_100_continue and not self.transport.is_closing(): - self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") - self.waiting_for_100_continue = False - - if not self.disconnected and not self.response_complete: - self.flow.resume_reading() - await self.message_event.wait() - self.message_event.clear() - - if self.disconnected or self.response_complete: - message = {"type": "http.disconnect"} - else: - message = { - "type": "http.request", - "body": self.body, - "more_body": self.more_body, - } - self.body = b"" - - return message diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/utils.py b/env/lib/python3.8/site-packages/uvicorn/protocols/utils.py deleted file mode 100644 index c993f152..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/protocols/utils.py +++ /dev/null @@ -1,52 +0,0 @@ -import urllib - - -def get_remote_addr(transport): - socket_info = transport.get_extra_info("socket") - if socket_info is not None: - try: - info = socket_info.getpeername() - return (str(info[0]), int(info[1])) if isinstance(info, tuple) else None - except OSError: - # This case appears to inconsistently occur with uvloop - # bound to a unix domain socket. - return None - - info = transport.get_extra_info("peername") - if info is not None and isinstance(info, (list, tuple)) and len(info) == 2: - return (str(info[0]), int(info[1])) - return None - - -def get_local_addr(transport): - socket_info = transport.get_extra_info("socket") - if socket_info is not None: - info = socket_info.getsockname() - - return (str(info[0]), int(info[1])) if isinstance(info, tuple) else None - info = transport.get_extra_info("sockname") - if info is not None and isinstance(info, (list, tuple)) and len(info) == 2: - return (str(info[0]), int(info[1])) - return None - - -def is_ssl(transport): - return bool(transport.get_extra_info("sslcontext")) - - -def get_client_addr(scope): - client = scope.get("client") - if not client: - return "" - return "%s:%d" % client - - -def get_path_with_query_string(scope): - path_with_query_string = urllib.parse.quote( - scope.get("root_path", "") + scope["path"] - ) - if scope["query_string"]: - path_with_query_string = "{}?{}".format( - path_with_query_string, scope["query_string"].decode("ascii") - ) - return path_with_query_string diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__init__.py b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index bb5a63d94c2f6d5c9d88ba164b02649c7fa1eba4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210 zcmYk0K?=e^3`M8lLWCZ~MVo~i1rbl+MqCf=G}xi-WSC4_dJ@mzH9Uq}kKoRg=}JHR z7ZUPAE@`?_qTTJG=lYuQuSA-om=}Udoz*%y-Bp;!KYT{0sY75i0V6qttBpFKCx+fx z@P&yrc7@9r!+-(M4ba*W{1j_)n|upwBWAMK6jzkcU=0NaK2Rh>EyIWx-{N6@=q*-X5$iiA diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/auto.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/auto.cpython-38.pyc deleted file mode 100644 index 9f26ee9600bb3b68dfbbea28cac9daaf4f7c0b3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 524 zcmaJ;K~BRk5VVt)RB4L@LWnO^qVa(XNC=e!2RI<43JShdX|iggI(B3`t;$Du10Uc4 zJR?_5e1Q|2rldV#YscE19q(9v>~?*E>*DQm{6Pu%DwEyS#$nBRez2O}0Aa}Ci1{D`m?!FLt_)Jjmh(_AvO-i7-Q+35&>TwUN9(Q9pB)!Hr zP9*m|TKJ>kgH~2WN?>*{g2_-tbFg)>RrpJon03(jD; zz@~{EYsi#gxlC9VMs@~iDEkKV0yG1;U?Q2YY-MLko(1R3Bo_MEHxH+PqRKt1-LtKG h7UGkGY*n-_Qx)d|uJDJ6IYMw~hwjq~eW&A;@e96(mstSvu-yP= zF*~#Do+ZT1!l?>WcB+z8IaN8TQj6SpOwKvksr&^w%{75=B;Z{5??x8WIh z8uG;*eGm@Thw&ij?s2xhzsq^Fej^HB@861^TpvCT zyNQUe4@8nC-6WFN_xYAgFf=`0^~3%k>I|M_j^I0?Ou1Mj9u#x>Xenp5Gwu6&rbTti zqo|cN#diarS$!B!X)PaHXSrBs*4w4ynEt3<9uE;4Ydx)jBT}o;g?6JvhVjl*U69nx z4oc*!(jDU1G2$$`r@Nc3I_uqNS2M@=J8t2Gz_A=M=a4IO)BWL z1a0Nmn&ozdjgAF8lA0XdG91$}RqH8vqFbk*{3(i3o-Y1e+t!st)jU(xNzNV5QgxCn z2NLG68YIqUb+&+al{HusZ-*_iCA@2_#g_4|vlVs*?*(?2y@YpzonxzbH`#f10q@11 zYnJ9MK}uiFmLKq~O(iV%3i;XSPB|nlsZNiHNB$DUSnp|aajZ}DBV5&3A8WpWHWP1a zY!1GaRwnil?#-{J&ZNflBN|c1hy}bC#zwD!cLVPx-c3d$7gf2W%9bjZRk;FMXB4fo zW$mT1c2131Wd|3yqLaxNK`MSuN-Q<%aEXN;JL)ie=x|lVAs~hs99)DhYOL2 z_u58Q-l~v z;Ipm5g=5LHM!^`)1uL8lx?Mh?*>bowH9X#mVsx7ep9N{)6Zc95 z#46+lJPrrgG_;P0`@T4b*0z=F@debqM!q{@I^|wP9p6(utNDI63Z%r8nZn(`1ezo} zC^X&H9RrWPs5f+|9v&NQ_`|!d{)%tIF-8|p$$V$Z)G511a<63neN@OAO(4%l`c(2$ zbF3edgj;E)sM%?iYT|XK$A*$lC#@Z76X*cVQxa%yWahqp z6W^qQG*4WmqC&;DsJMlpo28K6>@^ zLCn#8@p%w0C(c9b855IiLTX{RIF0FUbK7m_yR->%p;+I+^vskzJ-r_YVp{AcGx--? zF}I&LG4&lhl8i3xr~Y+2A&RGPhLBH@Avt8Y!=C0-S?ogHld*9h5=!EmBLN+6R#B=V zTGXmexjgF3k-Ni`CHpZ+i^6veLis#_n+|;L0V}qMesREaM`?&F#7C8dvKt6CJu6Eo z+#E-(Bvy*(PZj<{;;caZE2r;&et6f!`00-zmxSn7c;tVf01V*hj`UB>1M|Q-sH8d_ z-`Jq5-_Z{2u`#h2zTVY7yL?a`+mi}2nf0YMu1;)Lq4qw&|n z*uB%M5$JsdBj2mz0f-QQ^qT47*o5Ml=AGm%(_7ei(B%+;-Dl?(R>$E?4d*!-%vo zK_3l;yTx~d$6+GeT`oXf(rU_%t7U$$`NI!f08SKk1A>WbiVhfv-Tfd;OG?`yz(ceP z_hD|WAG&CIs8)RFhB3YvI_I~t&kO!bN@|8$duALuW$!cn&qn7qd3U{(rS+*NaYE%t z|6zXgspu=8^Qm&8x^%gae?m(YXN_O!jy@uWI$%5xiKE z>N}qkNuq6QhBkVmWMs-m2ME>W01&|+4Y^D^w^bY<@1QcJ@l3yVf?X1OvM-9=Z=#~u zz4WPZpdY~Bf!IT|Ag=1YZRG3|=Yi~oAu2YHy9o@lDSm+2nMDp|R(TvmLq4|^LF)bx zPre7k{+(AVg=u8I-nof`sKRDSTzA%x1K#zEFL4*s+6$SLJ{fS&3gk|hg9LG$1BZ)R zW+~^w5y5`$W;AdP;t7COkV{hC<$w?&L3@Vgas%FBZ2m7*%>2)6%4%43F`gruffjg}5m-j^bWdSbQQg~GLyEDMqs@g5axR9r&gEp!Ek zYoH7o;+SFV6B%zA$mz2r=02(C7NR6^hvtx#6t}2oqsT1M4{;6Ec0ET+vW4O!6kdZ4 z$R{6*_Nx10gSzga$n5-dyoO@AI4bcy>YuZ&*le;|b&S z_{@B?bwM5+)I`N|>N3s+kApA@wh)gUqj@YU&V#)(&tdxu(8|%RGP?R=LvW1jDXk|@ zi!@S_3^DycMP;d$!cZOJZ(=a(NMA(;0uMlJtnXA{5wxBOsH?*70o)O|DF4CPkS~GC z2QjcB4kC9`1r_dH3OeLpqK6RS`pwQw_l+Aj+~*E!)?sy_O6fZ3_*-rY#kxL-f-wHB z+uaQWT&V92)9v*)n{`Pp!*q1S8+Hk8zWn`CVu;c3!wpH>un zG5K_jNmKc1>UQzHI9Z~;2ihB?rp8Z=PqZIntxsrvLA|8(pUleFnP8pV_sc2I=)||i zI@9-R;u)*V#v+W#IeNkBO3Lh!DDU!tfO7_G7>HyD2am)_xojjXWYVtXVh7xH5!)b$ zhEPd$^~0Ed0c=N9T@uS(OeJ{a0;XIZyZzDSyHf&WXXhQmI-C#(OCa3dPDVFRFj2@P zJlTD?h{-S|Yt4wK64^VWTPLTS@M_%+!0k163o~;V0I9XBa;?*DiHi^j1=?8-nT14W zH3guwP}Y1qki6tR7hNU9-@x3gqLMN>XsfI&qC`eSm9UeD=W+5|s1*r>3~{9#MydEy z>fNGZPTn7&?Vs>SBBE6c{W4&-4hW{QZnOZ+lqj$Ozm9qct^vf)Nft~Uj}x&QEk`L) zr4u7yF-g+}$U7uVSt$7*kZ)tp5TBz3Q4%A$NAmar$t#k5#oNB1t!hUm0SIClzzZU! zs!F0!Jfuw=r4J0W9MJl=f>!PK(@JZ-dT(JzWA$xH)KzAbP-_%4TWsOLOq-;K=MaJY zjUE&A23gl%=yDr%rE$<}O+`xvYwQ`n(8U$SV-t~C^e~+xZ?a=DwP@#9BuNqC{=7JjRZv<4$n6JjY>+t(JeDbl}-G%u{JNPVJ!6UQsG6_HY_PDYiwXDEH^d4bMzO3(Ead z2$os9X*$U2!_d=gNVanFIRINz8<@2aa+i zvubhPUZbe^0*>0o{ap8!X98QK4Mt~Y zO_aLIGu_Buk*=z9A03-ipoWO4vyY-(6YEqjK_Ig*=CSw~jb7`WGH?ElN@Oc~Sv|x* zizv?Na`8FQDALVOh|mk6Vh6qSFGNX5M!99mF1K*qxIq01GROoN$Rl5V!POP4xAhI6 z;R;9y^1B5kJ;V(vC?hKe@Rj1+9oL8JT)u?t;yi79$6|bPk8bc99;Z_GR zKN9gO{#IwZI{jbC)Sr}{VH!p<&r_2xm}jRc?DSU4Gs$C}ds82jI6J0Sif>{$b8hGV Wd%HvNt6W5Z^gUrPj`*y(*!+Kre65-Q diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-38.pyc deleted file mode 100644 index 462b30853c86917913db2748702477bf4c54cf3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9138 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 diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/auto.py b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/auto.py deleted file mode 100644 index e3364dc7..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/auto.py +++ /dev/null @@ -1,15 +0,0 @@ -try: - import websockets # noqa -except ImportError: # pragma: no cover - try: - import wsproto # noqa - except ImportError: - AutoWebSocketsProtocol = None - else: - from uvicorn.protocols.websockets.wsproto_impl import WSProtocol - - AutoWebSocketsProtocol = WSProtocol -else: - from uvicorn.protocols.websockets.websockets_impl import WebSocketProtocol - - AutoWebSocketsProtocol = WebSocketProtocol diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py deleted file mode 100644 index 407674cf..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py +++ /dev/null @@ -1,251 +0,0 @@ -import asyncio -import http -import logging -from urllib.parse import unquote - -import websockets - -from uvicorn.protocols.utils import get_local_addr, get_remote_addr, is_ssl - - -class Server: - closing = False - - def register(self, ws): - pass - - def unregister(self, ws): - pass - - def is_serving(self): - return not self.closing - - -class WebSocketProtocol(websockets.WebSocketServerProtocol): - def __init__(self, config, server_state, _loop=None): - if not config.loaded: - config.load() - - self.config = config - self.app = config.loaded_app - self.loop = _loop or asyncio.get_event_loop() - self.logger = logging.getLogger("uvicorn.error") - self.root_path = config.root_path - - # Shared server state - self.connections = server_state.connections - self.tasks = server_state.tasks - - # Connection state - self.transport = None - self.server = None - self.client = None - self.scheme = None - - # Connection events - self.scope = None - self.handshake_started_event = asyncio.Event() - self.handshake_completed_event = asyncio.Event() - self.closed_event = asyncio.Event() - self.initial_response = None - self.connect_sent = False - self.accepted_subprotocol = None - self.transfer_data_task = None - - self.ws_server = Server() - - super().__init__(ws_handler=self.ws_handler, ws_server=self.ws_server) - - def connection_made(self, transport): - self.connections.add(self) - self.transport = transport - self.server = get_local_addr(transport) - self.client = get_remote_addr(transport) - self.scheme = "wss" if is_ssl(transport) else "ws" - super().connection_made(transport) - - def connection_lost(self, exc): - self.connections.remove(self) - self.handshake_completed_event.set() - super().connection_lost(exc) - - def shutdown(self): - self.ws_server.closing = True - self.transport.close() - - def on_task_complete(self, task): - self.tasks.discard(task) - - async def process_request(self, path, headers): - """ - This hook is called to determine if the websocket should return - an HTTP response and close. - - Our behavior here is to start the ASGI application, and then wait - for either `accept` or `close` in order to determine if we should - close the connection. - """ - path_portion, _, query_string = path.partition("?") - - websockets.handshake.check_request(headers) - - subprotocols = [] - for header in headers.get_all("Sec-WebSocket-Protocol"): - subprotocols.extend([token.strip() for token in header.split(",")]) - - asgi_headers = [ - (name.encode("ascii"), value.encode("ascii")) - for name, value in headers.raw_items() - ] - - self.scope = { - "type": "websocket", - "asgi": {"version": self.config.asgi_version, "spec_version": "2.1"}, - "scheme": self.scheme, - "server": self.server, - "client": self.client, - "root_path": self.root_path, - "path": unquote(path_portion), - "raw_path": path_portion, - "query_string": query_string.encode("ascii"), - "headers": asgi_headers, - "subprotocols": subprotocols, - } - task = self.loop.create_task(self.run_asgi()) - task.add_done_callback(self.on_task_complete) - self.tasks.add(task) - await self.handshake_started_event.wait() - return self.initial_response - - def process_subprotocol(self, headers, available_subprotocols): - """ - We override the standard 'process_subprotocol' behavior here so that - we return whatever subprotocol is sent in the 'accept' message. - """ - return self.accepted_subprotocol - - def send_500_response(self): - msg = b"Internal Server Error" - content = [ - b"HTTP/1.1 500 Internal Server Error\r\n" - b"content-type: text/plain; charset=utf-8\r\n", - b"content-length: " + str(len(msg)).encode("ascii") + b"\r\n", - b"connection: close\r\n", - b"\r\n", - msg, - ] - self.transport.write(b"".join(content)) - - async def ws_handler(self, protocol, path): - """ - This is the main handler function for the 'websockets' implementation - to call into. We just wait for close then return, and instead allow - 'send' and 'receive' events to drive the flow. - """ - self.handshake_completed_event.set() - await self.closed_event.wait() - - async def run_asgi(self): - """ - Wrapper around the ASGI callable, handling exceptions and unexpected - termination states. - """ - try: - result = await self.app(self.scope, self.asgi_receive, self.asgi_send) - except BaseException as exc: - self.closed_event.set() - msg = "Exception in ASGI application\n" - self.logger.error(msg, exc_info=exc) - if not self.handshake_started_event.is_set(): - self.send_500_response() - else: - await self.handshake_completed_event.wait() - self.transport.close() - else: - self.closed_event.set() - if not self.handshake_started_event.is_set(): - msg = "ASGI callable returned without sending handshake." - self.logger.error(msg) - self.send_500_response() - self.transport.close() - elif result is not None: - msg = "ASGI callable should return None, but returned '%s'." - self.logger.error(msg, result) - await self.handshake_completed_event.wait() - self.transport.close() - - async def asgi_send(self, message): - message_type = message["type"] - - if not self.handshake_started_event.is_set(): - if message_type == "websocket.accept": - self.logger.info( - '%s - "WebSocket %s" [accepted]', - self.scope["client"], - self.scope["root_path"] + self.scope["path"], - ) - self.initial_response = None - self.accepted_subprotocol = message.get("subprotocol") - self.handshake_started_event.set() - - elif message_type == "websocket.close": - self.logger.info( - '%s - "WebSocket %s" 403', - self.scope["client"], - self.scope["root_path"] + self.scope["path"], - ) - self.initial_response = (http.HTTPStatus.FORBIDDEN, [], b"") - self.handshake_started_event.set() - self.closed_event.set() - - else: - msg = ( - "Expected ASGI message 'websocket.accept' or 'websocket.close', " - "but got '%s'." - ) - raise RuntimeError(msg % message_type) - - elif not self.closed_event.is_set(): - await self.handshake_completed_event.wait() - - if message_type == "websocket.send": - bytes_data = message.get("bytes") - text_data = message.get("text") - data = text_data if bytes_data is None else bytes_data - await self.send(data) - - elif message_type == "websocket.close": - code = message.get("code", 1000) - await self.close(code) - self.closed_event.set() - - else: - msg = ( - "Expected ASGI message 'websocket.send' or 'websocket.close'," - " but got '%s'." - ) - raise RuntimeError(msg % message_type) - - else: - msg = "Unexpected ASGI message '%s', after sending 'websocket.close'." - raise RuntimeError(msg % message_type) - - async def asgi_receive(self): - if not self.connect_sent: - self.connect_sent = True - return {"type": "websocket.connect"} - - await self.handshake_completed_event.wait() - try: - data = await self.recv() - except websockets.ConnectionClosed as exc: - return {"type": "websocket.disconnect", "code": exc.code} - - msg = {"type": "websocket.receive"} - - if isinstance(data, str): - msg["text"] = data - else: - msg["bytes"] = data - - return msg diff --git a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/wsproto_impl.py b/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/wsproto_impl.py deleted file mode 100644 index d712963b..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/protocols/websockets/wsproto_impl.py +++ /dev/null @@ -1,306 +0,0 @@ -import asyncio -import logging -from urllib.parse import unquote - -import h11 -import wsproto -from wsproto import ConnectionType, events -from wsproto.connection import ConnectionState -from wsproto.extensions import PerMessageDeflate -from wsproto.utilities import RemoteProtocolError - -from uvicorn.protocols.utils import get_local_addr, get_remote_addr, is_ssl - -# Check wsproto version. We've build against 0.13. We don't know about 0.14 yet. -assert wsproto.__version__ > "0.13", "Need wsproto version 0.13" - - -class WSProtocol(asyncio.Protocol): - def __init__(self, config, server_state, _loop=None): - if not config.loaded: - config.load() - - self.config = config - self.app = config.loaded_app - self.loop = _loop or asyncio.get_event_loop() - self.logger = logging.getLogger("uvicorn.error") - self.root_path = config.root_path - - # Shared server state - self.connections = server_state.connections - self.tasks = server_state.tasks - - # Connection state - self.transport = None - self.server = None - self.client = None - self.scheme = None - - # WebSocket state - self.connect_event = None - self.queue = asyncio.Queue() - self.handshake_complete = False - self.close_sent = False - - self.conn = wsproto.WSConnection(connection_type=ConnectionType.SERVER) - - self.read_paused = False - self.writable = asyncio.Event() - self.writable.set() - - # Buffers - self.bytes = b"" - self.text = "" - - # Protocol interface - - def connection_made(self, transport): - self.connections.add(self) - self.transport = transport - self.server = get_local_addr(transport) - self.client = get_remote_addr(transport) - self.scheme = "wss" if is_ssl(transport) else "ws" - - def connection_lost(self, exc): - if exc is not None: - self.queue.put_nowait({"type": "websocket.disconnect"}) - self.connections.remove(self) - - def eof_received(self): - pass - - def data_received(self, data): - try: - self.conn.receive_data(data) - except RemoteProtocolError as err: - if err.event_hint is not None: - self.transport.write(self.conn.send(err.event_hint)) - self.transport.close() - else: - self.handle_no_connect(events.CloseConnection()) - else: - self.handle_events() - - def handle_events(self): - for event in self.conn.events(): - if isinstance(event, events.Request): - self.handle_connect(event) - elif isinstance(event, events.TextMessage): - self.handle_text(event) - elif isinstance(event, events.BytesMessage): - self.handle_bytes(event) - elif isinstance(event, events.RejectConnection): - self.handle_no_connect(event) - elif isinstance(event, events.RejectData): - self.handle_no_connect(event) - elif isinstance(event, events.CloseConnection): - self.handle_close(event) - elif isinstance(event, events.Ping): - self.handle_ping(event) - - def pause_writing(self): - """ - Called by the transport when the write buffer exceeds the high water mark. - """ - self.writable.clear() - - def resume_writing(self): - """ - Called by the transport when the write buffer drops below the low water mark. - """ - self.writable.set() - - def shutdown(self): - self.queue.put_nowait({"type": "websocket.disconnect", "code": 1012}) - output = self.conn.send(wsproto.events.CloseConnection(code=1012)) - self.transport.write(output) - self.transport.close() - - def on_task_complete(self, task): - self.tasks.discard(task) - - # Event handlers - - def handle_connect(self, event): - self.connect_event = event - headers = [(b"host", event.host.encode())] - headers += [(key.lower(), value) for key, value in event.extra_headers] - raw_path, _, query_string = event.target.partition("?") - self.scope = { - "type": "websocket", - "asgi": {"version": self.config.asgi_version, "spec_version": "2.1"}, - "http_version": "1.1", - "scheme": self.scheme, - "server": self.server, - "client": self.client, - "root_path": self.root_path, - "path": unquote(raw_path), - "raw_path": raw_path, - "query_string": query_string.encode("ascii"), - "headers": headers, - "subprotocols": event.subprotocols, - } - self.queue.put_nowait({"type": "websocket.connect"}) - task = self.loop.create_task(self.run_asgi()) - task.add_done_callback(self.on_task_complete) - self.tasks.add(task) - - def handle_no_connect(self, event): - headers = [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ] - msg = h11.Response(status_code=400, headers=headers, reason="Bad Request") - output = self.conn.send(msg) - msg = h11.Data(data=event.reason.encode("utf-8")) - output += self.conn.send(msg) - msg = h11.EndOfMessage() - output += self.conn.send(msg) - self.transport.write(output) - self.transport.close() - - def handle_text(self, event): - self.text += event.data - if event.message_finished: - self.queue.put_nowait({"type": "websocket.receive", "text": self.text}) - self.text = "" - if not self.read_paused: - self.read_paused = True - self.transport.pause_reading() - - def handle_bytes(self, event): - self.bytes += event.data - # todo: we may want to guard the size of self.bytes and self.text - if event.message_finished: - self.queue.put_nowait({"type": "websocket.receive", "bytes": self.bytes}) - self.bytes = b"" - if not self.read_paused: - self.read_paused = True - self.transport.pause_reading() - - def handle_close(self, event): - if self.conn.state == ConnectionState.REMOTE_CLOSING: - self.transport.write(self.conn.send(event.response())) - self.queue.put_nowait({"type": "websocket.disconnect", "code": event.code}) - self.transport.close() - - def handle_ping(self, event): - self.transport.write(self.conn.send(event.response())) - - def send_500_response(self): - headers = [ - (b"content-type", b"text/plain; charset=utf-8"), - (b"connection", b"close"), - ] - if self.conn.connection is None: - output = self.conn.send(wsproto.events.RejectConnection(status_code=500)) - else: - msg = h11.Response( - status_code=500, headers=headers, reason="Internal Server Error" - ) - output = self.conn.send(msg) - msg = h11.Data(data=b"Internal Server Error") - output += self.conn.send(msg) - msg = h11.EndOfMessage() - output += self.conn.send(msg) - self.transport.write(output) - - async def run_asgi(self): - try: - result = await self.app(self.scope, self.receive, self.send) - except BaseException as exc: - msg = "Exception in ASGI application\n" - self.logger.error(msg, exc_info=exc) - if not self.handshake_complete: - self.send_500_response() - self.transport.close() - else: - if not self.handshake_complete: - msg = "ASGI callable returned without completing handshake." - self.logger.error(msg) - self.send_500_response() - self.transport.close() - elif result is not None: - msg = "ASGI callable should return None, but returned '%s'." - self.logger.error(msg, result) - self.transport.close() - - async def send(self, message): - await self.writable.wait() - - message_type = message["type"] - - if not self.handshake_complete: - if message_type == "websocket.accept": - self.logger.info( - '%s - "WebSocket %s" [accepted]', - self.scope["client"], - self.scope["root_path"] + self.scope["path"], - ) - self.handshake_complete = True - subprotocol = message.get("subprotocol") - output = self.conn.send( - wsproto.events.AcceptConnection( - subprotocol=subprotocol, extensions=[PerMessageDeflate()] - ) - ) - self.transport.write(output) - - elif message_type == "websocket.close": - self.queue.put_nowait({"type": "websocket.disconnect", "code": None}) - self.logger.info( - '%s - "WebSocket %s" 403', - self.scope["client"], - self.scope["root_path"] + self.scope["path"], - ) - self.handshake_complete = True - self.close_sent = True - msg = h11.Response(status_code=403, headers=[]) - output = self.conn.send(msg) - msg = h11.EndOfMessage() - output += self.conn.send(msg) - self.transport.write(output) - self.transport.close() - - else: - msg = ( - "Expected ASGI message 'websocket.accept' or 'websocket.close', " - "but got '%s'." - ) - raise RuntimeError(msg % message_type) - - elif not self.close_sent: - if message_type == "websocket.send": - bytes_data = message.get("bytes") - text_data = message.get("text") - data = text_data if bytes_data is None else bytes_data - output = self.conn.send(wsproto.events.Message(data=data)) - if not self.transport.is_closing(): - self.transport.write(output) - - elif message_type == "websocket.close": - self.close_sent = True - code = message.get("code", 1000) - self.queue.put_nowait({"type": "websocket.disconnect", "code": code}) - output = self.conn.send(wsproto.events.CloseConnection(code=code)) - if not self.transport.is_closing(): - self.transport.write(output) - self.transport.close() - - else: - msg = ( - "Expected ASGI message 'websocket.send' or 'websocket.close'," - " but got '%s'." - ) - raise RuntimeError(msg % message_type) - - else: - msg = "Unexpected ASGI message '%s', after sending 'websocket.close'." - raise RuntimeError(msg % message_type) - - async def receive(self): - message = await self.queue.get() - if self.read_paused and self.queue.empty(): - self.read_paused = False - self.transport.resume_reading() - return message diff --git a/env/lib/python3.8/site-packages/uvicorn/subprocess.py b/env/lib/python3.8/site-packages/uvicorn/subprocess.py deleted file mode 100644 index 735a5135..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/subprocess.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -Some light wrappers around Python's multiprocessing, to deal with cleanly -starting child processes. -""" -import multiprocessing -import os -import sys - -multiprocessing.allow_connection_pickling() -spawn = multiprocessing.get_context("spawn") - - -def get_subprocess(config, target, sockets): - """ - Called in the parent process, to instantiate a new child process instance. - The child is not yet started at this point. - - * config - The Uvicorn configuration instance. - * target - A callable that accepts a list of sockets. In practice this will - be the `Server.run()` method. - * sockets - A list of sockets to pass to the server. Sockets are bound once - by the parent process, and then passed to the child processes. - """ - # We pass across the stdin fileno, and reopen it in the child process. - # This is required for some debugging environments. - try: - stdin_fileno = sys.stdin.fileno() - except OSError: - stdin_fileno = None - - kwargs = { - "config": config, - "target": target, - "sockets": sockets, - "stdin_fileno": stdin_fileno, - } - - return spawn.Process(target=subprocess_started, kwargs=kwargs) - - -def subprocess_started(config, target, sockets, stdin_fileno): - """ - Called when the child process starts. - - * config - The Uvicorn configuration instance. - * target - A callable that accepts a list of sockets. In practice this will - be the `Server.run()` method. - * sockets - A list of sockets to pass to the server. Sockets are bound once - by the parent process, and then passed to the child processes. - * stdin_fileno - The file number of sys.stdin, so that it can be reattached - to the child process. - """ - # Re-open stdin. - if stdin_fileno is not None: - sys.stdin = os.fdopen(stdin_fileno) - - # Logging needs to be setup again for each child. - config.configure_logging() - - # Now we can call into `Server.run(sockets=sockets)` - target(sockets=sockets) diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/__init__.py b/env/lib/python3.8/site-packages/uvicorn/supervisors/__init__.py deleted file mode 100644 index e2c87b81..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/supervisors/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from uvicorn.supervisors.multiprocess import Multiprocess - -try: - from uvicorn.supervisors.watchgodreload import WatchGodReload as ChangeReload -except ImportError: - from uvicorn.supervisors.statreload import StatReload as ChangeReload - -__all__ = ["Multiprocess", "ChangeReload"] diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 3d248a2148c79a71fad038fe1eda89126f7619e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 494 zcmZuu%}N6?5Kgw+A8T8RXOZHqhi(pD6p9EUqM!$hRQD3rP1s$UpJkG*)EDs?d<`F? zS5LlzCuds^Jvbo)-(5fO@J7Q`LVnvrq)8|#rVUH9%P<%<$* zDxE_-m?u8XudR5H$|eFM-I-7P7D0fdb?-7yOeVLX`|(~ps+L7+!9=bqB`gbP!9{wf z?uHj1|Cjb!%Vk!;Mh+S%0L@xu|3;S<{1t$O_~<{X!@mA#Va;fBo+!on2Z8$AHtxr; z+-k|3OhI~UB+ClVL6+9B$`q_jQlCqmn2E#AB`|50OcgJzT>0FZljxMW!pjNfEs{(k mX*(+08I^Hf7_7>pa<%SEwH1|;=eSMc>gD!=fDY+^9t6LWy^s(9 diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/basereload.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/basereload.cpython-38.pyc deleted file mode 100644 index b71325fe201006129ca7353937cb79401952d3fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2636 zcmZ`*O^@3|7@n~m$H{(nTY)H0f@x0IYr-g+o!*%obKf`|l z#{Qzg>C467Hk$qgLNLJ-)+&15;`!KVIeG84+`RW%9(pG!_5GI5nRI$(v|!t5RV15K zg?q?bbKf)JiPAGBO8ZW0UhoZ8_y5KYtXb!Fu_H~Whg$=cwWZdhh2c)z&Q!W8mC96` zmYu#F3~r<8H3-SbESSWF^NhhHS9s{Lnefqf*Wu3JjN~3MXbd`)moOW#K?v6~2ozvZHn21n5iH&tKZGF5j zh=p}YEU4T@slqhs%erShEt73kf@R7lQHD5TY8lu=YcH51$wkt>={n?d>eC`3})Wwty9jOUDf8aVtSEI zZsv&k3d)#G7&!=6`2@J?xjpZY>+6^=9WoW5_v!f~(tt070=QCy%z6MM0a9i-D7^3< zN3qG#VCRdhghD3KF6=H)rDVR|mS;+!yF(+g$LSHzoj>oetA^?O*h=TL!2`aGR&_>; zr@Y0IGcJ;8;FiM0-=GK-O^-bXOOTV#*&p5>7w!b5)ALM;p6zqu2jL&M$8-E-?$FtD zjNdDdxhRjFn2X@R;mibU?7_;OYbuipm13`Yh}lOiGY5ShZ2@gjR1T<2m!L0AmS^Fs zSDT~D8x%UAWL8r%c+`F#1rKUNjjF7TuD*WN)4kcMr+e0G??&n7kz<|hj`g;(1jX9U zl1znta2o38h})8UVpMeGo~zgT1+{=EDFVFpw=>m`j4id3xc$(UwAoE0;AxcgldRK` z%6f6So!O-y?ljld@2-U#_r7o5S>LdJfjadDeTzVOZW~*k!k<10&+A?R_wv+0^#Q$e zi3HKd3F_6G7}nABI}nUt;vU+i7oNA`01%GDJ%;;b;Eq;K!6M&eI5-0hLO+pJj{aLv zVq(fE_K&N;CCzw98G*w`D+`{dk$}V}!EqX$rn-u+)GOBSn;4F$28N(jsrqpm8EL&< z7N@TYhax&x?~*v@E>-nSG`#`=0&_rKuXA!*M`xU*@+Kb6om__kqmNmPP>-><&ks4O z03~lqJ%2VQ96G=baApGW$dhQvP zpRvoC_z(z=S)L9F1BTe=zv3V#j&F`Wzn`CSHGm!|?8H*n3jV5PIHy!BI{`gwR|elKH7N=w1q{48^y;Ym8Xai-B(8-}(ThW$(o6Vm6y z@X;_ziYJPIQql5Z~SVYsX2`w1A)$7$|>EqA?OkfP_#BtxBcV4e4yo zosD};y3%{br1w;G8j|m^$o~f|uy(}lR$rM|PY%XVbd}cA&B;;PEg;`j00neO?cxw9 z+`_59M4}kEg)VU^o-uUEkuI)iO!~NbGLRvzzO2bQu7TV@(+%5rILS=9G}v|VL#shN zS@;2`{v64S&sfZ60x6$4NJXC^b&R|4PKonPun0@8CfOc4(!TXg0(d# z_(U*+?2N%SF8@MnP>fVdt1c*0y}Q9x`}#+NnhciDhVw;8RLOe7oc0C3sKu0pV%;t(;UsjSI`69K*G4c zeCmAq#>FV_u5`PEvDF~{JltC-%-E1E_$lLvJxrCDw(HI1xZTugKTopeAjxH>plJq) zX{Ndfs-J43K*{EDY6iHkn&Sj8qRnNrch5i4js$F=9qVXiA_p#2Jf_O)K{8ThFe`GI zUTsx2?m>-P#6 zB?d8J00@QF>t<>9(0baOWXk$k(eEp;ZkqQBd+Ep9?K=w7%csT_vpw~(r{Aw#0Et%Z*!Mlec?JgBIMg*n+xtTd|voY$fsA=fUrc@8W;$9=V15+1xyaZgf-@T z#;dY?>?0tAq13u1K(P0sj6hiJT>yw;0#34H{$s5B+05bu!G+#F#+!oN0}75Q7EOWFaC_BSP2i?5uv6FMpyX;;fGd zz2Dxq0j~RZe|iX?qPnf&Pvt=g=qgrZ`gK0p@Z0KU-%$h8ghh0W9ubO$<8t>u*Q-1K E1IJtbDF6Tf diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/statreload.cpython-38.pyc b/env/lib/python3.8/site-packages/uvicorn/supervisors/__pycache__/statreload.cpython-38.pyc deleted file mode 100644 index e21ed698be5db76366096ae997c432f5504e96cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1625 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 WTP(T$9%fcY0l{4}@Tr;$C;kCiy`xe9 diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/basereload.py b/env/lib/python3.8/site-packages/uvicorn/supervisors/basereload.py deleted file mode 100644 index a2afc563..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/supervisors/basereload.py +++ /dev/null @@ -1,77 +0,0 @@ -import logging -import os -import signal -import threading - -import click - -from uvicorn.subprocess import get_subprocess - -HANDLED_SIGNALS = ( - signal.SIGINT, # Unix signal 2. Sent by Ctrl+C. - signal.SIGTERM, # Unix signal 15. Sent by `kill `. -) - -logger = logging.getLogger("uvicorn.error") - - -class BaseReload: - def __init__(self, config, target, sockets): - self.config = config - self.target = target - self.sockets = sockets - self.should_exit = threading.Event() - self.pid = os.getpid() - self.reloader_name = None - - def signal_handler(self, sig, frame): - """ - A signal handler that is registered with the parent process. - """ - self.should_exit.set() - - def run(self): - self.startup() - while not self.should_exit.wait(self.config.reload_delay): - if self.should_restart(): - self.restart() - - self.shutdown() - - def startup(self): - message = f"Started reloader process [{self.pid}] using {self.reloader_name}" - color_message = "Started reloader process [{}] using {}".format( - click.style(str(self.pid), fg="cyan", bold=True), - click.style(str(self.reloader_name), fg="cyan", bold=True), - ) - logger.info(message, extra={"color_message": color_message}) - - for sig in HANDLED_SIGNALS: - signal.signal(sig, self.signal_handler) - - self.process = get_subprocess( - config=self.config, target=self.target, sockets=self.sockets - ) - self.process.start() - - def restart(self): - self.mtimes = {} - - self.process.terminate() - self.process.join() - - self.process = get_subprocess( - config=self.config, target=self.target, sockets=self.sockets - ) - self.process.start() - - def shutdown(self): - self.process.join() - message = "Stopping reloader process [{}]".format(str(self.pid)) - color_message = "Stopping reloader process [{}]".format( - click.style(str(self.pid), fg="cyan", bold=True) - ) - logger.info(message, extra={"color_message": color_message}) - - def should_restart(self): - raise NotImplementedError("Reload strategies should override should_restart()") diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/multiprocess.py b/env/lib/python3.8/site-packages/uvicorn/supervisors/multiprocess.py deleted file mode 100644 index 94f7238d..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/supervisors/multiprocess.py +++ /dev/null @@ -1,63 +0,0 @@ -import logging -import os -import signal -import threading - -import click - -from uvicorn.subprocess import get_subprocess - -HANDLED_SIGNALS = ( - signal.SIGINT, # Unix signal 2. Sent by Ctrl+C. - signal.SIGTERM, # Unix signal 15. Sent by `kill `. -) - -logger = logging.getLogger("uvicorn.error") - - -class Multiprocess: - def __init__(self, config, target, sockets): - self.config = config - self.target = target - self.sockets = sockets - self.processes = [] - self.should_exit = threading.Event() - self.pid = os.getpid() - - def signal_handler(self, sig, frame): - """ - A signal handler that is registered with the parent process. - """ - self.should_exit.set() - - def run(self): - self.startup() - self.should_exit.wait() - self.shutdown() - - def startup(self): - message = "Started parent process [{}]".format(str(self.pid)) - color_message = "Started parent process [{}]".format( - click.style(str(self.pid), fg="cyan", bold=True) - ) - logger.info(message, extra={"color_message": color_message}) - - for sig in HANDLED_SIGNALS: - signal.signal(sig, self.signal_handler) - - for idx in range(self.config.workers): - process = get_subprocess( - config=self.config, target=self.target, sockets=self.sockets - ) - process.start() - self.processes.append(process) - - def shutdown(self): - for process in self.processes: - process.join() - - message = "Stopping parent process [{}]".format(str(self.pid)) - color_message = "Stopping parent process [{}]".format( - click.style(str(self.pid), fg="cyan", bold=True) - ) - logger.info(message, extra={"color_message": color_message}) diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/statreload.py b/env/lib/python3.8/site-packages/uvicorn/supervisors/statreload.py deleted file mode 100644 index eeb98ca4..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/supervisors/statreload.py +++ /dev/null @@ -1,41 +0,0 @@ -import logging -import os -from pathlib import Path - -from uvicorn.supervisors.basereload import BaseReload - -logger = logging.getLogger("uvicorn.error") - - -class StatReload(BaseReload): - def __init__(self, config, target, sockets): - super().__init__(config, target, sockets) - self.reloader_name = "statreload" - self.mtimes = {} - - def should_restart(self): - for filename in self.iter_py_files(): - try: - mtime = os.path.getmtime(filename) - except OSError: # pragma: nocover - continue - - old_time = self.mtimes.get(filename) - if old_time is None: - self.mtimes[filename] = mtime - continue - elif mtime > old_time: - display_path = os.path.normpath(filename) - if Path.cwd() in Path(filename).parents: - display_path = os.path.normpath(os.path.relpath(filename)) - message = "StatReload detected file change in '%s'. Reloading..." - logger.warning(message, display_path) - return True - return False - - def iter_py_files(self): - for reload_dir in self.config.reload_dirs: - for subdir, dirs, files in os.walk(reload_dir): - for file in files: - if file.endswith(".py"): - yield subdir + os.sep + file diff --git a/env/lib/python3.8/site-packages/uvicorn/supervisors/watchgodreload.py b/env/lib/python3.8/site-packages/uvicorn/supervisors/watchgodreload.py deleted file mode 100644 index 47ca9443..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/supervisors/watchgodreload.py +++ /dev/null @@ -1,61 +0,0 @@ -import logging -import re -from pathlib import Path - -from watchgod import DefaultWatcher - -from uvicorn.supervisors.basereload import BaseReload - -logger = logging.getLogger("uvicorn.error") - - -class CustomWatcher(DefaultWatcher): - ignore_dotted_file_regex = r"^\/?(?:\w+\/)*(\.\w+)" - ignored = [] - - def __init__(self, root_path): - for t in self.ignored_file_regexes: - self.ignored.append(t) - self.ignored.append(self.ignore_dotted_file_regex) - self._ignored = tuple(re.compile(r) for r in self.ignored) - super().__init__(root_path) - - def should_watch_file(self, entry): - return not any(r.search(entry.name) for r in self._ignored) - - -class WatchGodReload(BaseReload): - def __init__(self, config, target, sockets): - super().__init__(config, target, sockets) - self.reloader_name = "watchgod" - self.watchers = [] - watch_dirs = { - Path(watch_dir).resolve() - for watch_dir in self.config.reload_dirs - if Path(watch_dir).is_dir() - } - watch_dirs_set = set(watch_dirs) - - # remove directories that already have a parent watched, so that we don't have - # duplicated change events - for watch_dir in watch_dirs: - for compare_dir in watch_dirs: - if compare_dir is watch_dir: - continue - - if compare_dir in watch_dir.parents: - watch_dirs_set.remove(watch_dir) - - self.watch_dir_set = watch_dirs_set - for w in watch_dirs_set: - self.watchers.append(CustomWatcher(w)) - - def should_restart(self): - for watcher in self.watchers: - change = watcher.check() - if change != set(): - message = "WatchGodReload detected file change in '%s'. Reloading..." - logger.warning(message, [c[1] for c in change]) - return True - - return False diff --git a/env/lib/python3.8/site-packages/uvicorn/workers.py b/env/lib/python3.8/site-packages/uvicorn/workers.py deleted file mode 100644 index 1ac03637..00000000 --- a/env/lib/python3.8/site-packages/uvicorn/workers.py +++ /dev/null @@ -1,78 +0,0 @@ -import asyncio -import logging - -from gunicorn.workers.base import Worker - -from uvicorn.config import Config -from uvicorn.main import Server - - -class UvicornWorker(Worker): - """ - A worker class for Gunicorn that interfaces with an ASGI consumer callable, - rather than a WSGI callable. - """ - - CONFIG_KWARGS = {"loop": "uvloop", "http": "httptools"} - - def __init__(self, *args, **kwargs): - super(UvicornWorker, self).__init__(*args, **kwargs) - - logger = logging.getLogger("uvicorn.error") - logger.handlers = self.log.error_log.handlers - logger.setLevel(self.log.error_log.level) - logger.propagate = False - - logger = logging.getLogger("uvicorn.access") - logger.handlers = self.log.access_log.handlers - logger.setLevel(self.log.access_log.level) - logger.propagate = False - - config_kwargs = { - "app": None, - "log_config": None, - "timeout_keep_alive": self.cfg.keepalive, - "timeout_notify": self.timeout, - "callback_notify": self.callback_notify, - "limit_max_requests": self.max_requests, - "forwarded_allow_ips": self.cfg.forwarded_allow_ips, - } - - if self.cfg.is_ssl: - ssl_kwargs = { - "ssl_keyfile": self.cfg.ssl_options.get("keyfile"), - "ssl_certfile": self.cfg.ssl_options.get("certfile"), - "ssl_keyfile_password": self.cfg.ssl_options.get("password"), - "ssl_version": self.cfg.ssl_options.get("ssl_version"), - "ssl_cert_reqs": self.cfg.ssl_options.get("cert_reqs"), - "ssl_ca_certs": self.cfg.ssl_options.get("ca_certs"), - "ssl_ciphers": self.cfg.ssl_options.get("ciphers"), - } - config_kwargs.update(ssl_kwargs) - - if self.cfg.settings["backlog"].value: - config_kwargs["backlog"] = self.cfg.settings["backlog"].value - - config_kwargs.update(self.CONFIG_KWARGS) - - self.config = Config(**config_kwargs) - - def init_process(self): - self.config.setup_event_loop() - super(UvicornWorker, self).init_process() - - def init_signals(self): - pass - - def run(self): - self.config.app = self.wsgi - server = Server(config=self.config) - loop = asyncio.get_event_loop() - loop.run_until_complete(server.serve(sockets=self.sockets)) - - async def callback_notify(self): - self.notify() - - -class UvicornH11Worker(UvicornWorker): - CONFIG_KWARGS = {"loop": "asyncio", "http": "h11"} diff --git a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE deleted file mode 100644 index d49cae84..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2013-2019, Graham Dumpleton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* 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. - -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/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA deleted file mode 100644 index 34b78a03..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA +++ /dev/null @@ -1,169 +0,0 @@ -Metadata-Version: 2.1 -Name: wrapt -Version: 1.12.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 -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 :: 3.8 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy - -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 - - diff --git a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD deleted file mode 100644 index 9ca65339..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/RECORD +++ /dev/null @@ -1,15 +0,0 @@ -wrapt-1.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -wrapt-1.12.1.dist-info/LICENSE,sha256=43wT-E-zyaVBYbD8919NMC-4bOQs1hBhR72nnkGX2fI,1304 -wrapt-1.12.1.dist-info/METADATA,sha256=bRw1bYidctVxohCnPSXf4ADh7fmtbClv2UQkzW_SMXw,6489 -wrapt-1.12.1.dist-info/RECORD,, -wrapt-1.12.1.dist-info/WHEEL,sha256=TpFVeXF_cAlV118WSIPWtjqW7nPvzoOw-49FmS3fDKQ,103 -wrapt-1.12.1.dist-info/top_level.txt,sha256=Jf7kcuXtwjUJMwOL0QzALDg2WiSiXiH9ThKMjN64DW0,6 -wrapt/__init__.py,sha256=FS1Cu1Ai6qjtdTDMKVtgCTb0gW4mPOlM2111JlqpFq4,658 -wrapt/__pycache__/__init__.cpython-38.pyc,, -wrapt/__pycache__/decorators.cpython-38.pyc,, -wrapt/__pycache__/importer.cpython-38.pyc,, -wrapt/__pycache__/wrappers.cpython-38.pyc,, -wrapt/_wrappers.cpython-38-x86_64-linux-gnu.so,sha256=R6GYcZbIl_W9y-XQbRlJtgKqDUiCHLlI0QePiuc1L5M,198056 -wrapt/decorators.py,sha256=mUjuO9o-Gx0QI9ycp-N6txBv9cDwUf_7n2HlgtOmBGs,20247 -wrapt/importer.py,sha256=H-d3dCnVxGzz6UTrH4Xncqet5yPX9k-Lo5upa9hlQsc,7896 -wrapt/wrappers.py,sha256=IAcZRdrc38Bd-vq7Cekq65kAvoO1DXSzjISDQ1Hm6I8,33768 diff --git a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL deleted file mode 100644 index d193dea9..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: false -Tag: cp38-cp38-linux_x86_64 - diff --git a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt b/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt deleted file mode 100644 index ba11553a..00000000 --- a/env/lib/python3.8/site-packages/wrapt-1.12.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -wrapt diff --git a/env/lib/python3.8/site-packages/wrapt/__init__.py b/env/lib/python3.8/site-packages/wrapt/__init__.py deleted file mode 100644 index 7be739bf..00000000 --- a/env/lib/python3.8/site-packages/wrapt/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -__version_info__ = ('1', '12', '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/env/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/wrapt/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 4ca98b7af0324d25990dde24356f4063633f5091..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 999 zcmZvbOK%e~5XX1(em|N=lN1ow9NJak0un+6q#mIXLY3xXoLwhzyS7)h(-J-e2QFOU z$k*Uw_{ynYffJr4Kt*e5f9v^=XV#wazH2sXfgex5{2-rmLGTlen*;speOp!7XuiGAq=neV!A6vFcM=JiwR7`9_)F&l$6tZ;y&E>^UB*`TAk)y zcnG<}M>_PobK$`izNal$e=|E{u|3i1!`k&;(KMyAl-(5D$153IuH>nvS;n;Mzf>!k z{I7OT89o0aZqiLosJ5J@cV%s8W>k8?NJj0_)qUo4jq}(Wm;OUUUGK{cZWx4GtNCnY znd{8Ana+a1=pqt%`DSoPGhU|+O=M6gyXGUO<1fn z^*+}yYZ))KlKdk}eC$}W1veO+DPsv2nbMXll{$CL%O#Urg(a>pmF4p_5h_`wjHHSt zUY#V|#OmUXcyr}@7ED7|UoabEtMtOWo<4vMA%4B_JtADr6(O#0rnq$Ve>#E6wo*nH zd=_0qln`Y^1yM!dE!TBK1JOjZ5N$*U(e;4Z-x3(TgK7`aM+`h%Wpi?-^$@jP#0W7) zZ<$Mz`HQFby!AcM57C48^*&lE!6L(A&8(6vT5wA=^Tmu-l1G{Ez>*0n_YKqj)De>x zQOajgwzf+pA0Ir447Y6GuREs;W+FVcjfk&|&qEHfwW~baRQx&q0|w7q2y3~c(kMU5 F{{}SGIa>e# diff --git a/env/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc b/env/lib/python3.8/site-packages/wrapt/__pycache__/decorators.cpython-38.pyc deleted file mode 100644 index c7c0b600e04ad893fcf5832956d967f5141bc466..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9271 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 diff --git a/env/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc b/env/lib/python3.8/site-packages/wrapt/__pycache__/wrappers.cpython-38.pyc deleted file mode 100644 index 865ad08b4d8a4a3775a20e549b80e8651c59bf01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24404 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 pOd(s?QkX8>Q*dD)&E1)TnX{b'.format( - type(self).__name__, id(self), - type(self.__wrapped__).__name__, - id(self.__wrapped__)) - - def __reversed__(self): - return reversed(self.__wrapped__) - - if not PY2: - def __round__(self): - return round(self.__wrapped__) - - if sys.hexversion >= 0x03070000: - def __mro_entries__(self, bases): - return (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] - - # 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. - - def lookup_attribute(parent, attribute): - if inspect.isclass(parent): - for cls in inspect.getmro(parent): - if attribute in vars(cls): - return vars(cls)[attribute] - else: - return getattr(parent, attribute) - else: - return getattr(parent, attribute) - - original = lookup_attribute(parent, attribute) - - for attribute in path[1:]: - parent = original - original = lookup_attribute(parent, 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/env/lib64 b/env/lib64 deleted file mode 120000 index 7951405f..00000000 --- a/env/lib64 +++ /dev/null @@ -1 +0,0 @@ -lib \ No newline at end of file diff --git a/env/pyvenv.cfg b/env/pyvenv.cfg deleted file mode 100644 index 5d5aef25..00000000 --- a/env/pyvenv.cfg +++ /dev/null @@ -1,3 +0,0 @@ -home = /usr/bin -include-system-site-packages = false -version = 3.8.6 diff --git a/env/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl b/env/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl deleted file mode 100644 index 4924d956ad131cbe41250e2e7bdce3e42be2335e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23290 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 diff --git a/env/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl b/env/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl deleted file mode 100644 index fab3a7b2758c2c31aa62a2454244e57f7fd43e43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14131 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 diff --git a/env/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl b/env/share/python-wheels/certifi-2020.4.5.1-py2.py3-none-any.whl deleted file mode 100644 index c2220c20167c43c6e9d3a1b2f27ecaa53d1d13d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161630 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 z 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 O_32A76`j5UkpBaaFa5>< diff --git a/env/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl b/env/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl deleted file mode 100644 index 455eac3a3a287330fc94c76a95e77db8f7847452..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136755 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ÜYiClVZUOm&-#XKk7xscQL*=T$EzXxl$j7K z$P(c8qLj_u5MaMmqChRTqg^QdZJS-Y7~}vgi^JEp8*q$OVB=xMW&!a;(ux!hsu6iB z_!Zsbu;!egHMcBXb;GpRTk-FSiQDhsrA9#+^(+EF4T55xTIWR*`n2t`K!NPP5^p*q zE{Y>mnq&i)yZ6TlMV_}FPPSv9-ugw*&_410TV}?4ZhD+6}rD+3no|C5#XUn#Jd zoCqF=%HdxrutyuwrE;sqGny>Xxi=)J3j2^L>#Ef!4Ke4E_3!uG2aJ+pj@%#iE}-cOB5~skGx40A~kx&$T0DS z9&fc5o@B2KssofLyyIV7Y5lv;yEtasU%xarGsP0sN%+Gn%cnX6Z4koU>h>rRY@O+_ z$MF1KK6H343clZyF@~CAP9FFf(1#l{X^s`f)uSO6jERK#r6fu4sA_oEGTAT~)8^Z~ zF5uB?f%{MtMY!mNv+IXM5c+ftHGXI_DhO9OzXRE^+(jDjuRO7EtB0)jJiOCuR;M4X z4$K(Krtvt)5Z}QEAm)2N8UmhlG7L19n5V-Rx2ARYV-Yf*U?Y@4x z{78)u{*pA3{kNpi5#BAdSFUV9``JP!vVr`=tmcDvkK-RnBc;D3je27>Nnul_dF=hY z59*zDi{QP3F3w*k&fmi%!hb1nuI0w@9FA;`CLNowr>;E)MhF-B+Xr1~>7Uj*V8g6I zTZr(F7W`gTrBRPmv<(i5DzoucqitEKrwow_KDDPu0w+qG`qDHytxz`8_R(IcLCHDI zy80Z|rgD96@AtTaxXAs~^Pc+3fz1l)p=lt0cC7l71FLzC*X9=Xx1y1x3(|{&`}`B= zf8T1b-)C!6kN^PSSpNG~GcnY&GyK17^A7b(`_<;@kBcs#240m+@zMM*N<|OE3gsPB2Zc$LG!H(-W)#ZcRc}n7!dRyT z&=%q;SPDW$+GP+E;U2jHY!l-l6FZorNXL~6Wu7GxaPn(9KUy>`u6Q#JesXn8gfR>= zmgV*y&HOfN)dgycchu#xYyjLBDsd|kIqAQ?{uzCw!K0AJq{v#oP>Q85d2OPn`^Gdm zLYSh2P-GmXMQ@(e>LRl!#z7lffLZ*lS-rfRz?u32xV*X54yx3Ld1gZW`h#NiEbrE~0 z2WZ-ZgVwnwvk-Z0s{t%E&d>YB$3qxTt^WKm8j?kdOrJf5 zAkys{4zY^h56FWC9lD5l0ba~xc81^>71JNT&2G~yk`I>C_xlrtb9hS(3TxZX${b_5 zowqzV7eEsRIz8Atn9j21C`yXx%z-A6jGtoTmNt;NhJFs;xufyWvc6)~5 z2g$@en)~C5Jm;48&YcTm{W>~SV`%563`4&*Q6k_j7a?#64QeWEKM1nQ8Kz+CQ0KFb zweVE$U43W|W5=|$vTzDU2pthGIu4A_oUGg9og!FcOjCBV8Un7Dmak60OxjCTqm~d? z?VBbni{;o3-B7w5uctE){TbJ4=oIB3mqrs3(WpM^A>hy+O@LyoPy_2O(g$aipm;#3 z=kF`nC||pbx2Xl|`F6d(3C4RtH2+3f6Ft#Uw0KG!cH4lH-tO`oi>k4AOKetQ0s%9y zPT2{U$bm`qWUY36JEw3LvL@4^sQarNoW5yXxHN9wB|NRc10lunZ3ld_vE zxkd4f3sk|KMnGolyFp~vhYJ_m$4isFcovH`W`l%<|Buud{Tk3D(a%J!Dp@r%nxG~iPRSt7{5jG>Mk}*f!lWX8Y~dzIk~Kqk9YI{hgl6s^ zt7JW3J!l0Qk~`}P7e|#Sn3%m`7Ev=!f5l@rC{RVMs5Vhvl2Sv0jz4UrTT)M&A)9W* zY>m-EPNql~enny?kHhU9$sCxFAaR=+M*Dmp zTA5~B5=L%#4Eq2((ULKCCJ6vIALoRdqWQRIDla$=kGwfkFN`noJ!JcXOo!S6&;IkjxSi^fi(={L?EAt_A}$b58|$8 z#$^UIRBz0rtVEEFx}JaKR)>jkXI{QY03MDw$<8sIWX;q{ACJT5hOaIdP{anIKgRjh zrfQK^1L1pFKH5+yl4UukVSmLgntHE7lHU5<|6ePbyn&P^oWjFNW}_5;d+41OyK zk>*SsIEg{oN>cNzK=`E5oLw|CAdB%H5z2Mgk1rJ!-gyaAr8ysw`@3>dXiK@mU@R0s zreCjx^M`B}M{n|(vbU!<00Pu%)l_VF-7uyD<2(ph+2I#bM7IWAN|1RFc07WjYtC=@ z0m#;y-&`AzPAZq2Yj)Z#>!9V4pjhNuUHSwG3*?$F7G=TW#3o_{K}`FvcrwXFQ}tr_ zs3%>*iTjO803p`H2^B!O1?_#xm5G{s@L3JFh0>)ooGsRnvv@d3@{#2CY`@7a5}xHK zROTeCxT~MU${mSoQ&96tGNALfxgjZqOl|eQ2Mk;An?65w zSqmMvDbdWqcMFe0%qLl!bi@FwViPpR+B5gZ`})s1fdVQ@U!k0QLXK!JP)ZJb)hISU ze1PS$O%7D-o0(KAM7o>MdFUt?em$Q-7)+)`(ax`mg=dHmzg157ty8#+B-!(qWP|tv znqzBeRfIKE%U(ENnLUW%Ly-I*%q?l=mezU1>&8D6rJ;J?Rz#QssfhtvKp>x)ovUUk z#BeN}rfkxnd?&g2Q4RaQ>Ko3~mq~t;h+-qQ$u~ z85cE60ApfCEwu`%oNd^Uc>~4-ki~MzHn$i-7VIwByeO0>hfeb~c);ghuU0Vu%auHavZ@I&fAEN+T58a6HBWUYRl*#8 zfe;0Rs|@1{Dc`mtdU0LPrH{ZX4?|-%WjP|y%l3wrf98B6$VEf!%yb#I06X}(!WG%P zjHzT)H*y=9UczHW6j@%_tG4jrNdw1+853{1#=1tJbWzXDXx&d&^q`-oMWiYm&vY?C zbv7kl9Gq~8T3N$&c)bZ9+gW}A&P_yjDQ{1P%`7e-N!&#-Kk>s!)aVu&xEEm6%r%G? zV8MO}Hm$d~)3N(b7lGYpn2X>I$6)&UlIF8WAM;kuu8~}d&IE*1Mm1wgUkH`XKIWyp zHtnvqP4C6~dp=tt{uca1YX?SUU>Ns}_Q*UQEo(AHBj^&%CF{NE8fe19pL(rhWi`gT zB+L8hhSSPa)!OXF%CoMy5DJ=umX^}m6@)tS`ig6)et5a|duptCaRRj6K;@Fn3{}3c z(|B}Eo@=8m)q$46y@He+N4hG}?S5@XQ5UyuQvz1b&(+AsxSwQXf;rO1I1#^45;DZR zW7yBKz~d+U;AVxtks&aWYcDEG+#FF0h!~XU%?L;I3Vb7Nl^A=xcapV=`VA{=`o12T zOyo~eKTSgNSwOd)Ejd2PQ2@ZmbSmUf{>5hrSUzrN92!aavU$q^LC2@^Z+(wc9n6x5 zMZ*^y=2j+x&D<7ez^7~W&Fp1rjf$IjB$qR}_ezak1CDBGUE6{L`+*g|L&tGgWo-)M zxxU2!@-U9KdWs&wo)S*KV6k`AIGvKIICw0q^kKaJ46C4;%rubHkii6XGKd~QHGe7JW*CXV%?G>{mrY zZJdq9F&5pOVLGSr_soG_fJm_9 z9DW~?OTVd2Yw~`#dXk7|_8tom1#Zg>D+9A_Xwu9AwPj``b-HF+k3Yc8T!AW68Z&w8 ztO>b;rJ0A(2vf_u)42^e#Yz*d!4;g>mT8XZmtWW8tGK}OSZv;pt>cn3bQ05|f{H{X zb)&N-pZ*&AVxm(?=-4d~iO6L7S?wg(+9pS+$+w!n(4(KG6?XJCEzeH+F{lbmYA3ikSfQnCEb4y^&%#16!vzJlloL!-Mzx2oeV8b+$5% zcBU$*Zi1p6ZhNN1zJ>eHbG%|=d~lfld|X?VWmPKZyqz?`xVLv$ z7T}LpK`>tF$XoHRR!f_4PN75JVnc2g6ILI<(qq>ILmdPIZVEN0CYrNC9fNP zi*2y^C7YlDu&kPkB;wAhogFQkyU`q74*?SQOJKHE&ulY11{aUx)FhlW-cK! zPaHV#=1!gld<*1K;uzC7wX7Qv$SzKU<(3aKwt@}QH!F= zac1CXF))6`UH7sK()vWON81#b0S*om#p7b8}Sh`Ho6X^vfoP^(Hh3xU(fhAx&>>zloRW+ zuyQRBH_llKz!V1RCpEN;1)Z_@;JlOE{mJ!ID*8wScUC({&|)A z)AtQYlIEGMJamEp&DxZln8E zAxc2V{pkqu-fjK^ztm%b9<#w&?j^$P)a(KakR!2`dCP!SwD@pIN*R>K*~tD5>F&M` z*dl(1(x3)K)rss=j1)T9agS*pST9&U$}F`-Ng31qmy@%T8*64eGTi5P$o93lCJW{Y z$!mjT_)J!3l@hbuPaB0S^sdg6Qik>%eY0iP?oI8oo=Z+$XE)53rKQCo9FoN175CHS zv1~tf8UpmrY%``YYoWf5O8yxexJ#4D-@fc-PmD*Yl;;-QPzefnZ&3pf=e9SO3to~h zmp(6DNe{QFUHd8%cDV9)7*K6hqrSGWw>OF zm^R&@fq7kvCGGk|`|r0|y_oE}-{=4UY777XzFukp=$q);85laynwi@Fdo8zi6wYAG z{^qMZF+P<}54EJwj}J|Kv}}VB!73_KF(}~6uqi@yC4IH^^ozodbZOpePE`$B9oXu! zAcf7*G*!hEG9sz;;Bsl6=ljnQw8_t_owS?#Fxo7y+Y{I4om1qtX(oTy8S(PsxeD?3Z$-3-`!^KyGV@ADc*8Edycz4V{*+COS{xV(?wDp!ptZ+22m zjyO+heXZc$f7IsvrP}%WvG2Uu>Gt9Jwd}o$SBgIF**xyetMI7^`zGl%eYj~+TA8&e z>UH`vee^Y%)#bJE&HaAyRO5hkku{{)ERfBsPPyv=%7&h)x{{S?W&85V+jI|=O{DSA2H{z$UBCxSj6%tG4y zd@Xqcing=nAr;y&=ANt;YU-SUvKvx-XZ*52pgCxffM&*s}ABGU8lE^l?UJst+ps+bmTFT38(qBbq<@A*l0>6>l_ z4&MbY+9q4HZ&gQ(v)&)=+<69S%slriyxzbS^s#rboP9*;Jm3Zm?d@-mXkNtv_7*Qai>5hs53nJDs12tiE%; zoSZkUdvWeI)p;dqdzSiGo|kofT+xi5S80ASWZiZFETDCHx!T6WJ@lROdOhxp8f$-E zy`oiVb-7>nKUQhGzmCJxX6=944L!Z-w06EdpZK&$QGKj7!82%;3%0BgalP)G9`d%k zU3X;~M`3zg_}Hg)zHQ$(@w(sNJb%7zuO@YQeK34Jv!WHu?J~etPT!5{&DNPRF@E+a zw>jL#c#S)$>a7@FX-4E}4NM;zo{MzBoSrkJ8p4-1-G{yDB(W!JzYJwQm)V*&?#!&e z8gdTwI5W~Rp3N+tBpoo*#wG2y^-JGm8jX4#tv@txqaCb2H?{XzQF^65qPC1_tlw_z z43$+nn(l5r5P2Q)*k37{lETZG-bh8dMXDbPd0zeGyb)hED0+)DnpQ}4f5GIB1IA%D zExcHB#jwAEdG_C6VzrD~Jq=jRVIScK*=aNBv_1*Ph+%9fMkw{F+Zkmd%b%LV!KI+;KYk*lD~~pl`{MG$+w?VaFOK_W z@=swg-}((%Iaz(B23l-6T2 z#etvRgK3p7#s z6Lk%fl}>$2iU6_(LbB6E1>3saXMRvL(JC7>FHJQP%k!A-t%ti%E4H~Kao)p7M4tW}Uz(^^|H+%14-f?pggb2T}c zEKF(HB}@^4DGS7-pl}1@u!(K{7~3@TasiYkYbmD(&8Diky>>f?(1lgu6Pik}!xD9g z8P6kL!;pG5<*q#V&XpJ`SjP7{>sMwyNcwKGt@OeZhP@)t0c7A7=mWo7v6&fT8F9du zDE-7vHRu|%CI`JQs~@O9B?uR@@TNKd=~)Dvb_(sa_mKCs8GswFhqz1fUm@d32VMI|Y z0vvPDqy)oq2}=ob?6mq+Cs-xC6{zV6SGQF*^D89lHx%$QHl1KyV3g%66E>a2 zku7i4S5l+XWY5dH?rV<7#aGv^E2MC9mb>48ZMd+1z=MGLMYTC(R&%y_k=p=y%TxL@ z`WKF0WG1$Ld`5!O=}Cf%)vd5@DX`qkWo)qIjzs7tQ&R&-Op9-o<3BOmiRsvVh9ODe zkyapZF{xU5=&?GxLil!ou)-FT-v`o-1>yM+8z0sEl0d?#yA8cZ0g?c}1QeF1kPA__ z=)3j32LYl0ae=wOT*7C047g%H;O8Sk(VS zfS~)_vM#yzEgK6))ht%9F2I%}Tz=E6R2H&p88!M~`jm^q4t9iKsjEZhcZr7slTUn% zKR`i3T+MWJ8P+SSm|9#LLs8vVLXK!K2lded=m!V|L;?OP=kH>}KB9_qRz|4dSI}5M zVqno;%&(@6hG8)U4gE&0l&#`Js6m$|JZlOz-pEPhD(0C@7G2JVG>{6*?PJhyw1r!j zLnc$sCArT}Aydv*1Jr+#b{W1$^6ZnzR|_-@MNIjHjty=^Tw+G#He$wd1L%iBq5Ol) z{Lmx*8dG;5vEM|M@WqOgV7Vc2|KWf_(VbnM0{#6liIrBb2;Dv$-s-6IN0 z^etS0PVSE*^Rmz_3QPnW&O|pO)yebKV?hI~8AekQm~Os^3Q>Vb)A%=%of4h}J~3dz znCPZD`5EnQf9{Jr5K7o`rZFX8qN(Yx&inh^A5b>US1rQpmrhy!>VDq@FeOZ*vVULx z$H7Gl4^R58^Fz^A}+^ZkmYbNe-h|Bm&CH<)8+`Egf+)kO@P5~tju zdZva9Cp}1 zPB_A|;h)0&aUK2~i|Vj~)|%-N|BLcW?BB=1iB#VIl%50qSSQ~Pv7Radn)X1RM_Y=fwXyjgi4FnY+FTfJ$I07)x=0!eHnaItJb`e;j`9v2oGA z=m3cF7Px8J4ZQ!sA>YNW_1uB{|B&Y4{nBt52A~8khpA?$Ci72)O(FWzYyU<36(PKH z@Xx&dHAVbaT*SGvz~~trL0G~$d;!yduZAArScKK`1xWZBIfp5&;4hX?lQ+j`WI5;4|*g9+__+~69 zUCmHKR*YdPd;CA(zpnZM8ePTy#inDZCrye@Ffb9A`G1W6qE1Un?)gco!Y?ounE8KU z5%1b8no<9w1pk5+n2?A5864eSU$f1Bod28nfa|NK3_T+tl*r{0XTu;w|E?u+c=UuQ znd20C#4O0T7Hd!vRdsFm2oNRouiEY*AR_2+D!Tu6jxvwI9$VSl4SW(nl~7ewmyi|a z{@l?+Kbhit!Dg-L-oW~-^`4-^v&$PBTtof?7zZj0f$=r*psVT__{4w;qyEcTI3PK= ziv5dC$52=L@8gIdn}2Bk4f=Av>e~17E2NI0PeK4UzuaH#_FqhYp~vmlw@9GN|EfrD z=Kq#|F9Y*?QQ*lcLU(Lp`e|Z2F)#Wio8+J8{y!6VevYwTK5~PhAbeiXbl*{pYltCR z<}N08M5eHG(Vyq(<2wg84(<$dcJ6dssi>seZhC^gq_DlqXX3w|#+3CnB+%X6ybj`>B7-rh-4}UpD@es_z=xdB*;K z&9*`)>R;wqxvIC0%8ka|1I6(FxcbHz&6=p&wr$(CZQHhO+jjS~ji+tfwmEH2+dXsp z%}s8;`=xUJoK)&0r)uw7d)KbD%p}h)t#t6Yt4S^0o2>BTn^VQF%ocgF-6Tt|%@(`z zddQBBV--khQ>9!phJLlfDAMy1#)!#AS(fjBUUHt2BjNE>wJTiK67gr{{iXlu8*_b> zBpw+Grcs*84~=IS+y-%JOw7ULgwfDMB<0a&M#RVMqt=?|*%X(`2;(rqETAx>lLVjJ zF$jGC%Zze=OP<5ZnAhPvG+*3P#X=U-R%9ztS?rveiRJ}BmBT3=Uzm!MVrZe2uEGWu z8C?E_MoGeIngK&>N1VczKd6k%=J0?re9T2-GkA}+WGigM`l38YgWl0LT&a}(z~H(g z? zmG|yod+h9FAi>fk)EAdko;pA?GPCAJNCw5srhuh)V4^^Gt)(of<%%aN{f;e- zG;jpN9BB%npP+A0OPksCyg#zt0|iz%mz03uaP1tLz|+BY=shfniI*r0h5y_uWS)00 zTF4NNG_V%ke5`l;`~y0Pkpy`1=JLe=3QNkv&tRS(w7=Nww5+y4-O^aMh3ytZMjo_froto9<#4?h=&VD>3 zf_6w22k$;TA(3OTn(oA#7P@$=o}bV=r9g82)b(iQEqUxb;h#d;4A6m8n-SeC??H5& z!oHbyvmwbcy9OP!3;xce5MNGL*n1%^fZ0WT!+j%v4!1g#fktJ*aac*>tfdB?K14po z63&(OBo9~Kwix_t<^h=KKvASw_~ zpr@S8DifVU3hr_EvdH!Oeg2EdxQ&zBs104ZHpIgw35pZ?k6jjV10#wGaXZ+E%RjCV zA>z%VA2Z<+V%w-ehQMSvLL|krOiEHV-Nn<;C_(Z5&fLhE- zfnZ7MlLuHtIGBy4Ph!Rna7_}%-VqR;TA^?$OQc>G(~?xd>!khugsyWmp&;xrJh6iH z(4+iIm2-bEh&To3f@^usRPR!@vgf`$M_C^0C0J{N8C3a%@#Pdq>o@><7<5cIVv1P} zxv6=;cbDRsTpk<@*0tbsHo4HgnSO>dp)09_S*2RxaCvc%RytEeX5Vy&J?##+w{x~PSi4%=OL zZ8XNCcg!rH@mU@h(?|1UPTh&vHj_{EuT6=QUEqJ~$(;fhxj5oFTINLx>?ps}gCwoB zB4Vi3fhs-X*v5s-ss>{Fx$WxHg`dVfbOVw^iH)3+&{m4PuXCy>emaCeDOm3X%G)W% z{x}UfAMd@Zu+;iz^+^O>nEfkutgF)2zlN}n{(|g?f1X|05EL~dt!HoLRwqN>Qa$Tf z$*hb3=ARN$5l&%^GbgSv+FH|!Awen9kp~+?G8XpX0AV*}?#g?UmvA=TcwW$}n_cQ8 zjWJp1fz>7^bvHSmw+Mmj&Xq$CMr=dchE^5(So?8LaDjN|2NK3w7 zVit&y(O#5NM(}^5iE9Y6Tp&{RQA3H zjukLe&BCX_#n|d-S|jMIHYy;YHEe0neKY&3mN4W=&jIYlfFv%?wlLZ$u|6uX0g1mu zReG*d@^JR0R(dAt!)X{ca8o-!FMZ)X9F@f=2`Aa}ctl~-b!=WkRw*9!na$}4pr@Kv z4%#CD6{p+|;|d7rK23=ge6xdWP3-V}eW7r4bmy16EFmI|maycIYNc5Iv+ey(mjgJqt<@Mnh=YoE1YQM4c*0K#;?nhw^IZV?V2iPt9QTh^DXbV^|+K zu{`;Jt_`I@h<*=}>-TOvK!g%qPYi8rEnVNezBCul@>uQ0E7b~wF$-oFfw?;YnGB1F zuL!2XL!VGZXfvcrOI|Je$I~d;f#zl@$>&e7pB$s9plvIHQVO8KDRE?2K`%oLo2Yz= zUnXsaVIlKvUvPTv(kd#luqZj{K@5uXG}uKJ>v2$j z_+Z0m6Cq~>2%-fM|4}Kh>6?!|;H+F8MM2gdEXvcfP{LNN)S}V{!^eQuzE*iZR;l!1 zrC2HAF?Xoze`R*BpX+nNUfM|Skdm|0lmo!u_&P|?Y$$mt+Ee;bwz-J9krRUCVrO<~ zW~z#TF*V5(&qqO6!eCdzvas+-n9E$C&}R5SO~>;|3?|_Z9i1wt{W0J|_lpQ*Jy#KL ztF>dQrvaEt`8giw@D9b=>dK~)BkKbfs)}nA{{3$jslG_l5He9M15+^AP&lPV_~KUx zzr~v3U`nGOGXSqAgX9KzuQ@#R`c#qEBL8|WTdNmjU^D(Zw>uk2NEeDdWZU>S$3=RUx+fHI zblEv623VSC!E&i7H#zC>L9i`xVaA7Y{4K#a3NqDkHK|tHo$$a=o2dPq%NTR8$s{4h zUG(jxuu_~!dJ-;_P_hr@zk=;BZGYPBd%9i@+pavGK^~(;h2xTO-SX#bldd--#8AxSX-VxmE z6>5Eo6xP)&gf#MH5b_hLb5v%+}F^LY?n4#ukhMYA+2Q9Cg>sRFO9OK zX)s*Jt%csHbXe7G*Zpthj$#Ie29IY2_8cEjLY2XmRjWAI(HKd;Rm$xmLey#m$R@M9 z9CxGWCs9e*&}cAZcD+?AZdc2{a^wmwd)yCZ8hy})Oix8AySXfkWg}NZQi)i+8%)8M zWo72)9(mmB$}f32yy@r`Z0;PBk+Y2cA(6imQ&`t3VcehHfle# z8O`dW6upiQwa^86#Ml2Q*i7?>J|*t~M-%x{@R421;n5Bp{?`ZDjQt_~Dzx zoX&JBz}-hvkVfgbd6q@;j42*g_1EuZx2su|IK1bg|H#)efyAP<3Ny1f>TWTY%(sfJ zn?%seHflmLVZvAAa(YUYDi2*L_1#cJM#8PaC96LNz}t+VO)7^YN4N+2%w}83!4BhD zFAe;mO^DM)AU_TkRJAeA$=k)ntClyE2&6rHtS2Gt#4M?attsovZ(BQ#H~6dhV$V~e znO!6|BCAU1#n$9`=phUtsieZVPOif{w!d0ZS9*C!goyGXtGfS0M}conyRljJnj_L3vN`A>Q0mNJlIv>Vkk>+?MkDeLaDWuc^#S5;uWXVZQkpB2n%+j4-u{ zQjC=hqjE0lg8+C%W7-6%nvq8Q`S{fw=FdD+gagOoiCW8DxUlR)x`c_Lic?@Im2m;Q z2qpKW0yfixZKC*o7y@>yWp4{f>SzYU$k@{JR3nX7YPoP?@VDYqyvZBwA>ow79FfZo zM}}9pjo)L-)$kJ|iY>Q{aP9cw)u|)}F zbqjPw_Echm(Hx4;SOZFK*}Ft?<@=z37gWj-Osn_$WbVSLjgwwPsHf1@Pc^9PSX(%G z6?UV#)|GYzBUbd3Pg8bC5W;pBv3X8&(X`Wbg@D;_BC1kA!=7s2bDinj>&ZwPRduif zy38pPY=gO!1&oiCW{N~j#CSxh#kn2Nxx{MT1QKt5Ouk8K%G@PjoT;uZ2^0` zU@oPt)wF0%gGL&q`eKn9-*&_J^P4k(Yne0^E*Izr$g*@UB)rs*I?_;)@3N$n`7oVf zGd+ZZ$njGTshjYHWmA>>- zQxjs=H}}frey@8JIv%-rWj*4^OcWz?VuF0w&nV#4EqR14Ke)i%oFZ_>P$679GpplK zo8>V|1&@F&tHBd|gf}q$dzAEo&urJ(?q}oEAK#QOO7eme6oSc?2~!FP3;Cng>}-+{ zUkH@S6d@P0QqY)4PT;Hegz`{c4mwrTTzL?A$waBs*f$<7gaEac(00Ej6t~=5lmwQ* z_c&&?!QvWC}w?GzIJr(bWtyy{DAMeW~DB$Eg?6b}MhD#hy(FL9igI!Q8GS7mayDQcR3^Y*eqI7i%C?NV?X?1Zf{uBN}9G474u2Liaop#MZVK@`Z zeCFoX-Or2(gR(k<<5$(0d@x-Xy)syV7gg$m)974m{J_48sr^InP@S%!sg47>lK3s0 zTxr*xN?YCG(HZhVwOMY3j9)La)!w);&h0JG)-tgQI?kIq%*t_h8XW3762iahl9L}T z4qrXN1b7jMI_5ikX~r27JnoCquH0$mxPZV$bv`BYe7uC`oOb|WtaE|vq;ysHD508A2* zjSQvM(YT)lNfF<_WVh|d4#}E#7*fwZ_%B(FtT3(4fbs;k(jyifdZ_zO!Y+&6YCN0C zuN~wTEbl^foB7 zsyQ13*ijo`qjS`;2!UZ26>4@;Ez%Tgs^ml%;P-i}{p|2hY*<=Uhsx;H1~!E}T&KaV z`R}E6w1?v){BSP#_PB&9e^bD=caBtE0c`h3&~+$5Z?K<*6ZO=C@pZ^cH;rhj;}_2$ z6eQ--U?|^Xld_e*@txS3tP6wI}@vZ zd|bct?OKLZB8f)>%${gHQE^(4lDmbv3>Oumv{)XrUK4aOHmZ4D&s=nX?=H>dfK(-*%Qp4$hG6Ma>`AS3 zq^*20f3;dD1EyExq4m~t9@M>_y;KV!U74{kb~XK0`Y)FG9&&CTotR`<9iLwKspp91 zcwHpl;m#jZ5DH8OAKcZ27*Rc}_E<7#Rowm{)Kmo<_6(Umq_(G9$`+n=-O7)PAN1OK zvjN#i4ujw#rqt|cn#!2fu;&)suT;drBB_a-+~lxCMkOC_Iv)PB*(TFc(WsX@bXAsi z#Jb6~fRdjAawB@eeq7l7taf%vMb`@r@YJMgl`nfs6N}k8vk{H5QR>)&!@!V6`aikg ztf1T}-_=s-QTOz77!OJUwO5+ox+?}OrEa)@O_BQRq|50^N=F}N#dW`XsqQc7!TvP$ zl%}(vophB8<4_g2yoqxP#RFTNrEt& zw2%~-D(%a1HwfWS*$7=^kUCp~ZgK~2d?9v+3)$*sXMCl1O9i}OCKjq51hO1*HqWO^W& zsczZAa7m-d?_L+ zjUk;Akgm9;OxI7&O9Oavj*LrXFcNhSV0SNfB6AIgR=Cx^4x77Z|E>XvAR_ok;_W(4 zm`j6cHD_#cc%K4H;ii&B-j9Tm;k2>|Df5QI5P6HJ#FUmYIcJA44}Q5H6D+MZ#ianh zn@Fco3og`L4OaW5GFvE?pGUKT8_*(u%r_Z&+hg!!)a7exDirCsKBm~6D;qJ?1Np^- z#ho-qN9RZ=<-y}tTeN6fV?WW+%Mp>%~S;hnDb{WA0R;GU$G8^mxaGht&=$A%^$|c;MI(1 z7E75V%wcsRdlM_3QmRyRkog_lscY#QkbR8_jcOQH6M*(SZw6A-7c$6{P*L~Y(SPiT z5Kw%wpXRw$rF7y}0b{}}ARkLYSj!4wG6W>_o>A5z?ijT5=@p$BwN)J<&wl5#4cmw~ z7(}Sk&d^r1AaO}P0{AT!HrwZy@rvE*Q;^xwn5b#vaAsP`cp?9ss*%B{sh*YDMNs( zf~(*wu}iy1mstLRpKO$_UCE@m*p?tA^{R$W0%1K}2sWwqtLeL#7QJWgGd#2K6?@8W z0+HG$t*s(SToQQ{L?mFMbib-t9WG4_4qfZIjzRbWRR)n;G8|d0H`#`%JH)4~Qi(jh zucWDvNCx|O#BEL9%$pkdXsS%6D(>fyHjG&hTX9uF2+X9qaz-D+k=7 z*F@~mcl@aD<%ep9A*UoKw(8rEany&UwMnbv2#>d_B_i-~>{tDO=hJ+YrNWo`%ZW@F zMyZ|dgcj;hz=Mvag~ky{N_I-`$haD*xLsbM%BxMk@H zdC~M?uFjBqR&#jU+fba=X~M%;PL(uAD6H^t;S9e_+USlRlBmelwJ3RMoX?$SFHm|uWn zrdwG^<>xW$HNUg{p8@NP^1!Ur{R`d@&?AeGWX}lIF8u6jHP0@e#%vb}Yq=lEGg{}I zf0O4vI*Z8fLy|_w;D7<$4dcL18hG{R@eC@b#KA3dlaiCVC)liyYWDs?mo5%3P6Z zF#)2Pd);(8B|E~vD_mObJEB|_kwysGtQuHujU&@aJ8_oB8T?mQka<@hzR$J%X;3xE zGNPghP8Vz&1s_#R!$18_96IWes<+`TJTW#WPZOmo6fg(+O#ZeaH2wQIp#!`VSDaIg zVAAnYh%>W1XlA6AD+Pz<^Ma-zHJjk9!$0F;@@DlY)xi1vVsv!$f9o$oc$3>GpaKDP z%K-r)|IbSVPNoiSUJOp&t9tgTJ5nis=jto*1Gzd-Yh)OGADfyR;UIFbaiIp7&z!h; z#M-mhI+C@d?IS*)bsZJWGfKx^X5~iWx8ZkHdd*4mX=G0uLjPFe@w%S1%Ut zH&+|qey_eSDw@b{Tk_72JOj|q?A>)&M|JSnV^!4hymr4FTMaNTKX-S_>rTb@TTJ@u zrn)d)S5J)~^%buG^=k8HC*v-=JDIgs8N~%ys;z>wpAH5)nRXk1D&FVTUPqlrad@|XdcJswdSm#G82|Pvh7N43=N%mC$X1AoTNWkOlx=qyNDdeG3FGgmUJtf0*otmIwC^J4;bEg8d#mmb0`BUvj(t(K zwcpGrJI^-%R|xj0z{i2h%xJTi5esM@rWJoGuEY$q*IE5nr>!2IaVxZ={X;=j4) zzVJJ?ne$M6lUjN-wuwQvH9K~8wkx}Ot{&j6?O8^}<6NKUPP?=cjd45$O`?Fq-m`e? zSzNQ?&Hp;ybhCn-j3+g7`V#~;Jv%JgzNfSQaUbU=e=5CxmiV&roXAI896Gjmfl`=$5c{QGO9`y}e%Ar+M^{8F&_{iAgMD zdF-h{D;6u#JN|ngYuDj$soQL@8jkjnSD8`l@FB(5l0K9mvOm#fgVy9&DkLZvCB~p$ zQvA0;gQ7!aR}oN#^I^8jW=|Gi)n&lx?_c>b7M*tACud4Ml0)lmwk_!F_wvOmeX==+ zkW}=y9?;f7e5?o6ENB5+p z^*Mmwu0+FE4it+J#j9N(0_K~(y~jU-^pg@SN^4)N{uC$DQI_P z`fFF&&C9`l=sw-)KEHL=kH7%T=Xba3NI7v@yC&nu3K^~7yF|Npu0Zx#UUhN4b$Le> z#y=|X*_m&oOFTw)dTx}zmu;W^eNV&4Y>b@kSlicdFIk@&a4);vx+UX&ox+7LnKD00 zx^RjTI1>`*XvfJUEbf1NlrZC2SLZ*7j?A zOAR5eld_ma2q;&!Nqz1iN|rcF5q7MNlw2rshe3qiqA4**uz3v*G0=TC$O4ox2-X&u zU8ST|;_2C#6pg+t5&t2fXEpHr7s#?_{<$()icr!1;Q)~@`9EmG@xiN+Ot zl+0)GpOgCoEodyVrB0bJI3asM|IH&kZJpNSTICAz=3TkYM$%mtaJw--LaKUsEN!11 zDayn~>3$(c3kn&E)j8gj&yvVR3*_7w3Arc`Br1Cxmgoi{G}$2`E!lV`X#}<EM6QgEMS6cTKrfa> zP@EYP7YVwaKSKNH=pJtQ#RN3H~B zZ~hne!!;2>6@J8La&9u}5JiM4_IZgk#1*^Ym$!a0#v*JNUitdY6}3_rF8?9a1`(n_ z@J17HVv6BI9z_JCL7_Mc_k%KTk(*>0DiX)R2l!3Ui?!rnGthAfHDVFp8s(nv`-%{H z*{pO}EyVX6-cYSRQfgF0>9{A>FDhS=Hl)uIYI1V2$|uyvC{em32{gxvde%tise5X> zpo+5b{xW|$j#A1CVN!kGWtL-Ql#G-nB`PdfGdVOzW=MJS;5MVDq_?9e6-O6}EvAPw z-+>ZlRJJFFAv|x!nUF`cZr1VC=mI~V&}1*Ju)oA5N#5kS(6m#eWbSy8OIa&JJeHwK z3Sc!6xJM(ub4gI`Z&m(rKi7Jj$@Hv`>y;Qgh^fu(%KH2p-9ojHIhHgYgMqz+H$?F} zZ4oC$P6YC@)>`__m+ebHE+CJENhE_TNMy12z9as*@^3^XD(m34nR?p90egygFcoJC*tGVXnNl65>;+(9+HgQ(1}a1?gIpdYnC1szfpZ zd=|ZH5)~|jp}cfAr=SUsZGJbdxzZNSB!%|n`bBISp*xa+2B5)eTfgb?AAz*6jv>;H zC$*6)Eh+B~)_ZzxvZ;vV=rvKCGB6DZ(;wCQmU*>Np5x>SWNE zh7VzI*8ByAeIC>cA>7<9q$ufvw54NYme2;7)KBNysilTe))^zOfMMAaBw7S8@K&># zNNFWB*UACm0ch|tc(TzC;NOop0R&czgizVu^sXeuhr+i>3SU#mGP;>b%&A6dT=mc( z#J|s!ui=NAKQ@vB@RIMnB+x15)L3Rp=t#aIum!@W*^0j{@RYeG`2v0p4syDkp~^gm zTHy4Ja^zMDy1^-s>wl+SA>EkLF;LY+m+@kd#69F0d3nc<$YfoVt>d?hGs8@Y@CPm7 zA@R-MF_Q?WTHPhbpIhge4@2?QikA~gRw@M#A$KzoyHIb%2DfnmB?U*Ekl`37@h?hf z`Iss31V1I9aKYqa>mo2_prWt};-{ERf(?xE9Vy$3T0;^dZ$r^9HlnlBnaQp&1WJ>Stt7;qsf#RV)#UcCH6Ar zQvaHgEOUi7_^AAFS6faj*^gk9W={#W`TgEE8GOzvu8s(CvEk456f!o?v66|D83 z*2nzbzYCh=GtH7V^lRc#h+tR_l1*ImQRu0sZitnln5?h*WRn7Jx)Wm?qr-S8k9tQB z9=3DD_ib`IrR5)m(wz;=tIOZEkOwTv&6(p@hbQ|?ENWJKLc)LwYpJLk>U&j+#9tAR zXIzO7B&JqA2*5NuQ$mqWa3p>mMl%u!#zvnJqw-TL6Td))&gxLtB&!bN!r}qaJ6Gmp z{7haZoGXr4)hR~UdP;McGgrf3{yninp4>bZkvN(C{nw*s3X&yoxzRT7#~je05Wjxi zMboHy1xFeNg~_TEQ)v?-aF6)lf-ARL;H1|Su>)q)N-f!T^pf7^ep1gY&S^AMYm~^? zJ~iERhjPQy(!Vq#^QhtF=jFL~v>jhp6x%!iIhG;az!68Lda9YNkp+Z@>Foa1Gp5v(?aeYL6IfMf# zs4Ad@0-|;r3lOAnbP9^g<|84;Oo}6YDW+hDZPC6&uwK}rIobN-h8?L6x&sK7kD_uJ zYkr$jCQe^$uqmiLM&&1UN3QdG1BAN?CNo%e#8iorubZEN?BJo5qW?^0X2FA#XP?BLOwtRh7t#Aw;v1U4RbZ9-s{mj4zm z0k)JRC)5oW_M{Te{6!W-S2!%T?FyUy5eXbpwzvrW_P$8oP{z zix)Er%Qfe4S#SbMxpXJNDSOb@c|KBQoDn-i( z97PFwt%$@4u-qUgD(7aLjNre{(Y%RBSHU(@HaA{w*tvATn51KI{JLhy_qBK!E|XP5 zBJhYsP|mqu&bk!k6Ptf_T*usuBV)s8ecS3=)A;ifX~~KF4pj_7z!HmnhU#O;koBF8 zv4IwmP$aB!Zk@;6MO5IkhVE~)N<56z_Jt+C>LlvSm#}2oxp`x@|Gw`Lu9qV*yx-hd zkJvUlqkVcL+(A2gogvo~2D4IM0Bt{XK{QXAHTzK zxm{C$hS@hsomRfU3r^#pat`YzD&i%(@qnNano!)|BN)T(dXViTzl}c#PHPKN#3b-W zkmJjKci!At4pGpQFP|$L6l+-we>o7^UP(ewLvB`nqs6vV+#x>~n7b#J=n^DMBZQnu zlE@`D6Z_)r$@KQ3XFFEzRvIh$ogcld>eU-PQiv2(jax|JM7)ueMM_r)k7}uBa?D*1 zp2hLKH#g^}@0R!0*ui+&M7!(i5b53+a1C&1?|d)Ief8bHg?j#TJ$tqJK6!n9_whFR zexiHd`DQ{OyT(`}_xHzL zVEJ5UYK3J*{i@nLVm)Fg#%2O{KUJm)NA)G3VAiACrPuB7BJksCu*UJjgx_|$_0nx^ z<>a7+hxsa|`_rA59khZ=}AzxikmuJ_a6iG3EZi)E0 z%deBce>cfKD#C|)3dDaAMJejvZuys3g4vN{s>U93Q<9MO`9uTS7QvHEOg*Q9=({;l z(dtJ3%iybmpIHbzr(XxAmeBceBWLg|r)?F{bKfpQ_M6P2qJWou-a@6>qKeR79ftl? z<}fP$MG3|p>pSQ&@`t;b_PK9a5$-A=PoU*Qd@o`~rqV!Q@^-a_aA)(BeMt=G3W163C zfR2xQRZeHyIyH(Rm4|j!NA^ay`T*xcQj(^<-kuzA>u#YoLR3a4dbD8tT~Gfhult7y z`>8l@G7a7#eKPHQO{+FQt6xvd0(r*a2M{e%%PgKUDYC!PK8N!TuyR^>5-Fgw#nh3J zosY8Do)h9E;>RK(;2}Io3^!?B`ZFaI%ApMn6OEfd+TSc68klfo8^i{uq)1Ae|8Aw( zeh`W(kbP|V_FHAk^VZm!U8~30XJa}D4Vc-m8dn17lU-CX2UxPn#4adSd!`Gh-id!G zoW6V9@OX|!s_fXO$uiQ^V&9BzJptNrt`=(!`v8ucR1m*Hi}Y;2$^LeA)}BfjxYyVV zWE}R{Wy)8xaWf)93Bvd)dZjtOHUQA{)eirJ4I$Z&{URY!u+HxlF9D7`w!1l z9xq^R$F|8y&pEC)>%QrBRnww{48hm^Cu+K=h9|IgpDVvAmO`3P3nMp}s z_k#aO(V4OrCYK$))iB($ef4+wc>B2UtAhHQXTB+lXV_f-U7Q~9<%8zfyNi7?|K|`X z$ZCyHEf;dwq@q^xZx7mqng27e!>Nwysm<_xZ5rS%P^NM1%@r^Yz7ZeztrOE9IFDQH zcwfJtd;LrB9_618o?@OLH%<}`EbwH~gl8vJ*X#Pf_(eqoLEERB48E>63i&=CkPSJe z$z_rX<2+{FsYT?9v%vT;S{e8s;of`~ZES_5Dz;*SxHS6xKoNB5+>W~<^*YRX$)>I> z7(#;J6|a4*c$53NG}9&NtAcUIgn*tm7s&7CLf^1%(}Pb171h(<*6bV+mLKnTd}#&n^Lc@w|38Droz>(N5iAf8B?}M`{{Kk6*%>=nnz-9p z8oO8s#ncMv&;%;>G6_2Da{9o&-I&VN^eywB$RCA`15%REwbcJXua^6{n; z$jin55{0YrKk7x+eAUT4x!2E?h~}EW&>0DT%l)QRNP(J1M671Zmo(3a^+vgBL36Fy zypKC~#>r$R`&ZY0L8g1DXVzYPy%_ym(M5Nl!LzG zr`fYV9EDU+^5yAFKb0Kz99aD1fYQvg9jSt9!N;L)=3*0J0(R zkXbj{J1s_!@vv9}kwgZ$EViH-?*Va>q|d*!NWCkFH>_*rUDTNC>*OhxYY{vt#?TGm z>gC$kC4I;prg+$?083viLT6pm(JqINoHWgjIa6#UOphFC-WPwm1=gtiTAqwj3U{EOW!(F^)+URzr z8^GK5@q9gPSH7Dx``P~f8+`Lr`3S(!v6nvSpleV9!44^1Gk3G_GBp>DE8 z8DrlWvkTNpN7$RPAMC26bjC^FTN*k!{dW)IrjRtY zUy?CV_?t^~auK1k*T*Y;&J-?U%&J$9W~O>Z)VqJ0q$`=CGUX6JOI-Sa3gZ{UgmBS6 zp*^J`rR?;N#HJ;t5Qs3IgxjZi%r3nXYj(Wb=)?Qp5I+0#nioBK;_fjT0NixWE)w)y z|M>@T^2!&nAensRK2T6-_ddNbEpPN)GM{=I0w`f=#k58BWR^@GE}YXg$=agFqnPIw=j3?BpZ=%b|rcb^D+w&E2GBjA%0TiCOnh4v3q|AcPEX( zO=7lgB~gvSa!t4%DyO0#Dd1?B11+Y(-dNulUyZ6?L)1>8dqKFY0HLC7=Ga!i@nlL2)w-H-WP7|MsM1>>45@Rf3d0{V7u0<}($b+$K z(KM(TMPm(W%EcmA{wOppdM*e+cvYg1RuV1BpihFQXXC1blE;)wp{bJk5gNyx?35)l55$}Rj; z7$Db4T5ZSaE@9&U`lt8I{?;zgqfD@S3DL96Bh$JaQ`+84G?rOEdddW|M=pv5B~?9N zwo|t~O#{=WJ-?h*zM5f#H>nhmqf$ztz-hyyyqa#|E~w>MrvJt%-aXj)2#Gdm$P|Ek#wC_ecIetXIY*aE&6^0oZ3O?Vz?7_-J;!d*N%alJYoj4s@qrM@ zk^A@_V?+ss7RO2dNG9{grelR3RPZOzz?JN&7@0+98?yP<)#xu0LfEj5^^i>75YRg} zXzDVbm-9TqV5l_k3k#C-5>6!V97B5ZZ^j3+k)K&0heQTr4+%iXZ?b2Yw;~+7>z8Dj z>Crihk|t7Ltj-ofBvH~$cs>qp)ca)M{iP`@L_10e962Jm=Oo8xIz^m)D zFbDiOd2go<>;Kmw4-z6?&y~@C85zyBHdKfwBY+9@CPUfRMk&k|&E}@pE&JAXE##Ta zj!u@N8b_@S1Hz*mQ{9voC*~wf7q&hVaxmMq{qxrssW2+~s@f!~@`hQnzc9^#2|g5AD`Mq0=5e_P=mn1|n*ET1n6 zCjos-sJu{@`s>%d7L)*Fx7vOX$Qqp5^_U+u#{mzJ?fCqfaLeOhVWf|rO9ZB|l4X%2 zH>3hc-~oSsyF1kUN?{zH@_cfihqPF4tSBAewWXM$zZfrFh$d>Q$ zJc5239Z}Ez^+&2>HDva^p>oojva@gdwP6Y-IO8_G$>&WxO_vis)qV^S&`n8gG1ctB zt$j_JiSafPu&eQf5^<;0S zg@)F=i5cl3YhQfeg49IDjz<+SDPO}5xkG@6uejCskCM&X$hV36yQ4b|y0*GWcwtt| zv-AB^nq}}u=oj}XJ=P^d_YDE^X00k4d{=4$gXApD0vl?BB_FaVH0~sLD=28&BmI@g zDca?8P>7)8-4O|_FDLLOV`~aj71p8sNNE@Wq&c*K??8Xk;h7HxPuNki>3gCQ?pLda zZj~T^K%9!*uWeED<5CWk+xlZ-ZetOMG+uS9% z$DXko_|1+Jjj~DY#LqJe|NYx*iy<7~`45h~@7Y#LM7^$^yZefKDz|38?&->VE`7e! z+a>yv1xh388_|W!DR(0~Uq{sSS_y4WGF_53nwvx8aXhe_Bxwutqqz}c$hkip`?sr` zc{g>8x*XfTHey1qiOx?y?}!z*{+YQmu3u3ih0*VA<8@eK%z;%)tm|HM&%u#6@hWw{ zcKUC~zq3Q`;vFoWdyEhuTuwHy??QGuUY`WE-m^ANb4BhJL<{FZzFc3atj>PIdk;)! zI#%PU3(^`KAf5?(x`9Fh$QS1&3czB;w+>x6}@4P`unXh!aSSYiv(b za-XAa2;c^KS=ylW$mOaZ-SrE9=2;gX+zNUC@?=CW`S$oeb!qFBPp~SB2Ur{In;9!{ zrTrA3@*aT|4f~=TJ4MwG;hX!-u?#8Z9*o`&bL2daeBT2f_i{Mpb6!zrx}pEQgn7x< zpBQ9rx=T2E=?jWYxBHqr=2Qtp(_hG+f%k#{|6)n}7o_zH9%WlWwt=9WDSxcJ{yp;UZ#A&?UHV74cl+IcM~H>F`FaQnjBgZFs0R1- zzsT_>?lp2i;DCVeBz~U%1+7iJU99cwtWEzPvevU#+~L9an{Q~W-(o{sR&$f&ZQV*p zh3TX0jjE*n9X2EvR4K}m6ZXID+uv>5(|+u^Ab9l&5GHd>zp~IOk~MkxRKQjWfHUz!9&l(lC52IBAFR`{U(> zL7qbS*NGjA>|u);>V%z-&3Qm}8nnb;g1|(}O};s8k5QROg$cq@bLQyN#v+c%C6LT_ zzUgXMDho<&gIC1|E}A3i?w)$Kmx>=`&E7w*#!2qm`xp^@?*)dga4+A+pVO$CLcd|H zH}d}KrQ_R_T4tWFw>LPuKAPisZhXx&)!&$E=8;F)eoY@5PEO0};bORFW_=_m!Y<43 zNY!6asej@;6LSst0v_IL{=80*FHSqTXQQ@xh7y}BcKev88-Lrj%huafUDxLc=QVT3 zK5Gw;`8{4Te@(<-ME!|X;f&y@aLZsh2^NZ&BAtuD91Fuy(RU~zX_E-YZ3}1Yi@l<` z=s$l5_G*3m$JwATa#Fs?!j|m=t}_5X-Au5FyCT@p=!rjv7`GFr^8zmT#ce93Ma4IC z;|L7q_c`J~jQ-elT~z(8g#epShX1DEzoWND?rnjOsXn`cd8a}hQ`Ajpzxg<(O#7ml&>Q3$$iMemBzCSIaY2#89|HzT{GuIO#VO*q z?dpkbZPv%s77m(fMM+Hs7aDQfc$y&_l)X&yx0vAUPj@ zO#Sh&XD^9#57d*zFef*x*)!-JfkXz&d)`EdTmw0$&*B+|COmLwXWZG%{ta8jh@yWT zZ6|z|aQP4DD;>C1$fXo_1xr%#Wb8|Udb%|fm9@yaDDeS~Md4PUEyP<;_SdmVCD3da z&BSI_Z%8gt$W@z%`A`=q!y<67%yc6Sz!C6Fc0kXdm4rs;M0!^8TDrp#SS%xQpq03X zIHF({=AvB^Skm(D0%C;hm4pckf^{o!9pexUCQ-7N5iralDSgra_MvSV4^aL=Y(+ytK~u57^(O0IBc1MrbL0+lOq2WW(cE@2SP!2hE$ z3x(ze{j{*3mX@B)ydo7P8zmb9JVF*B1()oWKnxrKhJ_;J4zvl>1gr*`1RIf_4P^ro z1&OpD@`f>z>=%73OJ+#&jxw1k)hG5qp2GOwD_XkbY}qia6bZed|3lVWMb#BGS=-pb zT@Mo6-61#x5AN>n1os@=-3d-`cXxMphv4qcNB7@-@%DeUYmc#R_RSv8npHKYBs4;5 zjy5xPX-#Ba%$vlb0Y^YzWE|r6A72(Q92mu*OPN?|iWrq$ooQzF{%{gXL>BPf8Djit zdnFWAq_;u^$Yz!sG&$z(m>w2r7$7cU2ry|2+Yr7F4W&`+ra8vFCPxk9hpdnhd!U&= zw^2Xroe(DiY&a^>G>2~p`!~E;q$3FJb|t5Q4z8?6GATgbgNP(k;9Vr_@ra5^+;l0F z==dH(epdJjVGdCh!)*@DdE-2ci>`pmLG|D%j+??Q83Xc6- zqe|f>4}t{Iy(zNe2wiVU89@IxTC5AjuqvgUg;sn{Ntna=1~GbxdodXa3N+5_IMg-8 zOtd}4k=Pv-Kb3kURd-5t>e6DXvfe#4u{hn6;&7L4I{0gBM@iKQtgjomqhgqP5?>rs z5} zEICHDSn3`C`~w@7485CJy@Qq>_Y{=c`NCe@6-MHVi>UWsU+r7+K9;a_p>F_rM^6~f zxlHn|EB%gS6_BKfJE4L0`N}9q<#>&ZyZb5hsTz+%(M>YpwYPI%&>hst)V$6L*f&Fs z9CQ|paa?OxeZP_gxlg~dcSeuyd)Y)>$xePB%-+NjL;nk-=&8H*^KR(fU<5o8czAEW z!k*)>;&8jY!0h5cphOcp30{kPP+QvweoFs1@#DpNAits8w9g2^1S9TVBZsV&+Bt$X z=*2~wSS_X}4_B>Lh>rrHaFK_smn*L5rho1A{*BJ82MfRIvhI66dwazW9U^m8r0CLy z1a?BbQI4%=Jz&=nn>uhz578NWKCL+VUe%cE<-NVQI79t(Kfo7BQbIloG74S-k+8B4 z%Yhi5@j$j-Y%bqQn0>L_qGuLJ9a*C3%s#G#IHq%w8BWoUK zR+tkDtw1SfBLg*)=|Leav|U^0c2#p{jp-qf-sefTl^k=`C!WBOxc_T9g^Hf2anPK9 zNQ^|KOzVs4U_f#RJJGy5GrfD{qa1=wSI}SG^O$+eR%9fA^{~H?m1WkvzFsivy-N|{BY zT6rPvVpnK^(0p@9;j&d{9^8z?E%xGFB16N4P=hLDhv`LFF$GhfBmJF4qT^?^qa~cC8ca z>2`20kABussB?%j%&)EbF;CB>Mrw8|(UZ&)&9rX_FIj8gbz}zpLN4iTCYBQ;+BVc{ z^A46;-AF%WB246a#{;Pl-xm7VN#{402SHb|eD0ivY1bS-4tfpoAz#C~|IDb(NEl@R zEGLe7Gb;MEbOIX3ME&0#6Gr{R<883+Yq$L`cFSlHURnyYPg`FgB{0i@%@Kby+`fHN zj#|>skp1H#Y!~9uAx}@4DQO(c1HG|-9LvScT-F{jF1E=fi3yGF5dqDMQ0U*iG{anL zU_3!U$_w8rvqRHZv!b9b*mS1!G{@*^hdkf8wiYJ9!`JqrTfN&!*IxnH@N^R%jFfw9 zqS8`Z+_ciiVtp~0HS5tUKBIT8a4cZ~j>zSOhi_)4JDt)Xk)On~uo>^=j3KR?nPNc( z-3<`U;9)!axazkoT&+U5v~}@h7^<@N9&tDrux0TcGE${C%;*tK6hUU9)YW4Smo+## zGB~SS+vzqmOzXzT1enT$4oF?L=IWfe9x16@$c(mys=_$eigB^2svUdoCS)|e;G9Eb zN2n@PItj@Z{}UPECDn$OYZFWU?^HZMkZ`DaAXXent++QfLNkn#o4+0SUnUO=u^0P zktZ)B7_6(q2V8`v@^7AGtYrZX9;8;bOCx-R=n#B2{rVs_>-_P3Hh{};4=-ieyxtMf zgvjfTZW;PC?t32DwI+#W_T+C%#%HRR8Cq4FH30jES#=@3iQ|gnFM|beUDK>LxaW(e zZ?ru(zF9JPD+7FV=r4KwV)vf_p>+G`kUNG*=@V^&DW=`KbiI(S)B#i6L)4WBGqE$e z+wkUg$^11Smv7mY(nm#Wk)EpfXW3w&dgr6y)T>e#d~v62*Zfvc6|w+KjNv-_t71C^ zLduhmLPzeMMH5cP^c_L_rXa5`FJ91I(++wz%Dpzm&u_k0ND+tI4LjrLO^;0W5&=C* zF*rWoZohMDuRXvD_FXCZwstOl=)57ObU%Imr!4=`Rz+h42L=|)0tSZrf9?+Ezf4WP zB2fNUlDD;A<3|6e)Mr^Xn!#46BQ+gz4S$U_OR%f9L?@>S_l3vIkP4)YmygeQL4Mr2 z%-wt<9dW^9xBx_TOHzKH8s}ppm<`rzKl;db3%QJuKi+@ZzPh{lvMTvfv9E(e{mmxlSQ!DrhAs7JnhB zK7Q}uahJ8>%z(&qdO<#yK+_#=!PO0wDbOFtyW1xYyJc_J?3qwsIpx1Y^?{vbawZga zvwRY=hs8cfq;l?@yi91mAyN_Bk;N;p9$B@eg)$wn{ebP;oaND+;R~g~ieRSO5f+sb zZhvBsBKeG^?_Fy+(;7f%Caahfdx>2j=oEaHq#_OYd#Be=8pL&2mO=gJ#}oOV2yP5a zllnxTl@6m5NxZK{jfljT8INiyxL{FySt5`Jx(0YoJCK{4Yzvyp}}&D#N>U zQcJ-WiDktPNN#(_L4r7NKsPuZ+O^p_L)JRl#?e><1>s z2l*<2t^pn9D8>FNQFx+c$sRyY8GGn02O>;&NMA&NAaTv-#nb-NNnQQN(bLJ@)lGc# zB%?+4Smhnf~6}l6<&fV!vBZ7ph`l=ijU3U2?Z$7Nj`d;Z8MYP~Pq->G2^i zV-zkW;5r5Nzm<4*grj_FDW#N63Qfi$-{p|7+d<}G7UBBq(SM~RT4E_+QCJ#Mgr zy=%Re^7zn$M`672I6loZ*fJX|(V2AYu;GFL@=g+alip$Wv4N&`As{$-E^+|x^;*!d zx}}cut5;$Lk=^fCtCsM?XIg6I`rmfM_M*bH++H%XVkEI->HNmsFr5;Px)Gc%O$Ib{3+g}^uAw>Zd69`WQPg0JVK>jP#UHNUT++-!}U=h zx;0t9Gy7U1$+nE~q1f)v$~4ksrHw5!UI2~Vv*aAI4I+&N2GbJhGVwf+WzCM_jgHcd zEY#(QawmxWJ8=j3*+U;R*(%G^g!=j+BW(~Bnx|Z63dFn5MUYZ_s?Gd42bLLM=)&Fp za?A>OuO}h(?a>rUo0}vsS5GEjyWWx+QuaZ4^B|6wkKz*zPPCspnX&#PoGbTArvkj{+kWiBF%r8ZTGi11s8%wA4?STIEdcq zha5$Ts$5^@Sc!#<2$+_ZeDmv#0IdO3If*53I_=D#GJe-W$0{*-#60pmPnP_T3Jg%d zlDhN$&r;vTW1ZS7cl`SOYJy3f0JV-EPE<1zZsOm)-Q0Wtv71J@8G= zirej!jd@&rPCxUJo7C?++-}>fiY5*JqsJ06m?WQ0r%TPr1xLQ#g8OyXnd2LLn02u? z-9{8Zx@hU`a8bELd}W(U`cIL?Y3;-{{5M?!_f?E0&qUoQz|{6{{M7R=tK;O0m#$I6GiEk#kWYO9(oUjhvWloua{V50YHcCB z?M0d(8uHspxrj@{EXNYPLj&IVX&6Cj&C=~U*I@HZUm2&Um?vkL{L(5~kSvGdb-p=8 zS^lGvto7y^Zl-#C6FNaz1em7!P zrTlrii!o1k9fLwj)pPlYzfnQEhH_M?j0({yrec`Y7Qd~WvGBX@`u=a+KXis$9Ot;S zC{~3n|6(mcxVbkYB~m54^G)0bo(zhw_-6k^_*)M2W7J8)}UCXUV+vFbm-Swnn5z_gN|rZTR6D&CT=bS)-J&%FKXp zcbnbv=)ypbF|L@PkT{t{I))%Q|!K@<-Uf7eb>A>LKWv zh7d;iV*g3^uv@_6k8Hind=*jWKQiwkLurl+YnXfxm}jK=Q2}^2S)Tlm-5o#p&Ed?V zK83^|$bdY532ugY;`LZso~?xyrk%dZm^v~qocEk`>IK6%^suz3eMo*O<4hO#W;T;* zt*~)_JLb^!_nNYA)wE**y6%O?Di7{2E66&VH_t%XBpcG1*EyKS)m*KoBq1Dbb2LD9 zvuR?pTR0`;{XU1#5!0jf@}1aq!J=aDq1JHCVY=(p`4SBphUb8C&}&J=t7C0-RZSDy zS)!->hfm5N=-bYV-)FM5rhz@KYuI_=?9==2CLvC9VaTgLWo~XCgdPmP&!JXF3M+yx znaKV|a>z$lTJ5_&&*ofxYxL#0)xy0Ix@1L;aV?mjJVWypZthd2yI05PUbowEs zjApR2ol3d2nhNXF-k%eEV(EK)9D?idE|mQpXoI`=g8Ot1)oau{_iT~ysmg6tGN9Sw z&>K!6oK7m*;et)A;=`P~xo76BJy0??{Xc@f8fbmSK^J3pL#DA`mZ7Ma-VL0 zDQ?&)&S+E-)wH*wVocQc8w?5rWEX*cR!5rLP#sr-e)u&kk9togftM!mde-IRA9wcX z<6`4&<0D1WXL}p7Z5*GOeSuE~!3WoW0$Pk&1+e1_&=l#x!0`SLp#6VYzW+;T3tHO$ zH8kP-SjC;b2&?srt@0N-x>mkw&JQjvJ9y%G`8X-~>eXf3HA^1e^v}+%n!RT4F{B4W z8dV$hOrAsDC0a7SCxuUmp@1s$6lY&o*5-EH>Fei(k**TZL%=o2E*ncX=px~imoO6w zL(EPTr^ioc%IRp*&99WXcl>Dujtpx~bij%Lh9pYZ)4+sa(woaw_(AMlMUPpP1Q3I{ zR1N)pb2;b(=RJI5d}tXQc1j$%(H&z!Kue{D;h9RsS2~`l0NQazKA2)T&-Ny_)U>TG zrVz~OJe-NOB*QC}3=&)*AMl0P$$e!G5PzK+%7@wr!uZIsUh;z9z&dKA>IrVrW zc!C?4xFy)QhR8xm#-rraM1`8E+k2g4%Y@zu2rqT6|E!8Zxb4}_dPU{g`D6PDq!m-V z0(OavO|hexvAcT1FZ4$#l~)_fL<>HX!Pb0Gq&CMm5vD(5ECRjF5L{F+h zH5`}SsKUZ7)xk`CGrn%&Rr4(v4zn0Fo^i5!P=@|h2L{34y=nOAP5I9#%hbuiAaEZv zT)@DcKArNAnR-nIENs6b6Pg+cu5Zeg|`*nM}QCIJf`G*=y#b5vS(qN zS?eQGSJY9gOaGr2`WU$E0?Z{0LiOBx!WfQ*c1&1~IvI^}ae8EzJA+s7gkU3YNy z;%LSDlE5Tz-mPB}9+1XUGw#*S`O)}{YLNU%s}u5y4mlNB!;?&V5WJ&Wdny!X&@R*>@<4?_McBd2HM=6q8cI1=A2n8E zZqz#3a^+bvP1loLR|Bx=am%&n<5q6i28GG!B`;VQ26>x9nu-^GE<67&oCA?Zup##m zTeI-$w3U<7Eetduac+pSha{7b8-Ynnf~8<@{ZNWnF-lty78E^v&7vVemWn|31ox!2 zk?avSN>#`Ov@obaK5}}ZAOiMGj2f}oz}Y}$P;44=#2KwMYxZ1h5+Vi1o`Y zd~l@r=r)qQMi6YZJ(!t13J4+v6Cxly=iqt|G|z}IVqEA%1IisWxGmW3#H*Nnk7bF* zCtR6rxiAIh(B&!vuuv#%)S3Vd^gr-)81rOC_NRENTSNHH%cv4nZL9(CGTM3XZP&IA zd<5$;ldmcI5;*Gm(1%jbbuw**Bdasc1TXnyBGWtIYbMyo0g{E!>G8t_VPXkmWeusu z()oI`FO)bFs0fnZ&8=7Z(TfF?yjO8Sx}pYDtH-eY(6Hqjs0B9vM5^O7)v?R98-%gK zmIt6~x52d^MJP2>%h)%25Pm(=rF6AOYBqwHO#{Yh(=+#oQEs3>f05XwJRc=Zv^97j zHV~8&l%hmiX#5L3V<+Jzi0nfH1|<{mb5PC9-olaYBrPTf3C@G{V*grA|gClXhRgM?gnyaV}XJvRm zp35RJ>epC8KCyBW3H}&tDeDqx@f2K3e?nf}#AhZ>IN?%7_R?NEZDn~F{y{J8dyrWG zqH-q{W;^jBF*TJU1B7P0IzibORIZodhFmka|1acu)dFWml&&D8Ur=jjleKW5=m9+~ z{=UEVP_-Hu>LYYnIX7zfFlr>oHb`Q=n8hjuCnGsD4~zZ6-(hNfrWcv_L-ZyP@&*wy zwl&+BFx^5+NyS?(Dg@}%GZY(t(=YRRVgEe;2O&#>d>5{QgJRtt%Y;FJU8eb$G-`o$ zk&A3?w(Pa~W8M46j|fVPj{TbzKF}s4=OOB^mZek7X_e2wQrDReo5%HdpGZpW=2yh< zK3Y@hap)b6f?`8YyvE4S}=xLaKGdIbV&zX#Q9WC+4|JI-HQj z*^YNbC{;GDYHXa1Supl5wucwF)?YTsZ{bE9qqMVLB*QVOs_K<`t?T$(-dg$;RmUm{ z%)4vpij}YbGF$1}IB~)YYsP==CUWWi^wJ_^zgK6nJP8rxhc2bLC*;(SucsxYEnWt)na#7besgk6(nKo*fC5Y=0v_<~fRNXVEx9p>AEu?@<(^0;U zTe^}{`M}Zj%?2cdoqPa$6)c59bY@YBA~X%1OvhdU!#$%6+-bY6jP8=2k)P zBH{`37**kmlac38w)}dVfM52#EPvn$$9w#){L32g>Yn|yxFa)sZy3A;)1>odC|=jW zZjA6l;hWf2V3!Y=2SICBb>7X+4-wp{qKoBg@j2pO&-r1B!`TI(b)F-a=YYt-lMto3 zxSQ-J?TNUeuP!R_cb9g_G~8av0kSO*#nh*B)mPE;ra;nHIixzTl5nrW>zHf(|AfB2 z9@XCq@L*ufU#i^y9hS9lvHSlG%i6E;eBCpufa|+?4BH3siGs>!KhiVmdkUpu3#eZ( zsW}s1)#KXZ*XP@oKRZK`spHYlxtsLP7^^u{e(pNBAB?A=eLGs9`xJa}xVzqul#@q} znXHUH>N|ek(YK5`FWbh_6_n(e+I!`WLgyJbi{JGZF!zf|An(23+arxC`fBO3%NnI6 zvj`yETX?r* z%vYK`a&5U;)}j9zhdCm{o$;KbXoDrAFCyS(+Bm_aNiO};)>s8A>@~nf+TCZ*625}b!tyV}3?l>BY>JrA-{ATW+2cb)$|fUoaCA)_5(n20sSV+XZslk>a( zX7J%}`EdUDmySHyIkOZnHWpBKYJX{nP{Vr~EFC}PqZs+hsp!heqo=ocJUGJ85?k=8HvetMd{0TvFYYb64Ke@vkxTYq6%q}(Ir#iB(cH{O(Nv_Jn}SIlgE~C> zhJs7=@+*k<^kZgbo*c0y7lrG)TUvWicYdZp1V?)|cK5Y60bHC73(REwwbT&t^O195v z#>~sYjIx2W9(h;atR#zXpZS9Sxj1JGzi(r1DmmU-#%)Sy@Tdkat$0L31W~*PZ9;`s zG;Pd0W?_KbA0W6sezfe2$}YdA{b)fOjXJV*D|f?CvyhDRnm3;|B-#SQga5PFD%kUV zP{fe1jtFrcvO4>K;(QrTZ~Z2M>qLO^M{luQItnej(8flR!wsN>?H*=5Sc&?ZOiBK)r4g>)lDgmt6G8hao!T@_ODzO@@40>t->zw*wD)oFS zDNZ8^Hr#gtA$Evo9BBebAT{VWA4Cg8FWPjFf)T_FyGlY5!yqvqxFUdE&9c{onf3)9 z9C64B^%!amq6}kuPD3{!rACRwMu-ozEF{zlVTBn>(Fy}?P)tyQnj;SW9f9IhAt+o* zMEAB(+P_Ko3bTlS^YfDObHChU6q6Ph_a8NHOva4?U>SV zL00A4=i1jB=7!yDRoh6;1tok`ahsHd3&sL?iqM!D) zoyw@K#`3RL(`=w@dRjVcKQM?wUn}Da=#E-e6LdQfHQyC$sD>L$*RpVf*~FV$Dz8kz zQQs4%c;VP7i!m>COh6x?gnF=Y`~TsJ4nAX_s}atv?9XI`doQ z0&4?KJ>|w~ri%$uk6Y7PO}`pA5tw{gU95%K$FIbL+Al=cd#lHE(`P`2t)+kjzZs{b z;!4*ffcmvzRRx@vpV?!-?om#wVQo&8^P{2cx7t>eX8gR3JJBuV0gFwYm6=PErcD!J z!LZe`Q~Nn2XE}Bc~F3SQo=XZ0pGre!A zC3%j0=`bOd?5j~d3W7Qf=DINDik+N|HP?*(*^8hOz})%xC25D=Q8~S9c(=2!vXkNM z+swPBwI~^LOqMPQbJ#o&GePKJ?|{j1_ZxqAQVDMjuMdT3hL84jdD>{X)L@h=J}gXL z8(!03?_#Jc5cpmrj^?QvP_f%PXhd>UIb8nPf-#N_dq!}(m{d0SGDE3VR%N_pQXC|7 z`5}8ABwKIid&a~3K05}=C}$+&qyky&vhy^lvz`CYfNj^TcG-3%6C~n*u;T~Z+k@vr z27HYhaf|^tB{K|p>D5Iu>4AQ|*PE5%O;jg}Wpwz2t=29GKeJ)hk9|F1Y*Z|{VKYnQ zuv`C~oOECHY3;c%)T1r8+mHGeVe25bo{tYGmHBT9!9Dkl~QB6{%j~QYHR#zn(n1L+s2w{ktt;ePblJ z^32N{$oK8ra$AfmL*OQTb4*jWI^-#D{WlF|1Zb zIlEsKR{OH0HVwE8&6?HRsQgVt4yWnbz||@7i2ifIEOW9;VpL=Z_55>P5nUPG7I_U$Rp?4XrNmTFLd(4&Z< zu7`8C)@RdN`r%4({*oWrwR)zui1;#S?3bJ15vhaXcTI;DyP^m;@r-v+6?WqqQGNKx zM#%D;ThE$#+tb1##l*n$L|_!<)j9au7Ybs(DLFPA+r1J%b()L3f=(o+1E=MpUfqn{ zIx5v5^vlP;pN@JmKzISRvc-HJ{W-nyLFb+f{&p(540f3DuLajm)o4Af+34fn>*{tk zw-)r7z0U(YsyNMZDsFjMHrUR_O;In-w~4CCclAJ&(7Lk{_aX-YiS912|Kwp(lv%->FCNDG5?w;(1bXazfhI=Jx*CU$i$>gtL2gcl5M-pyAEa#`hAk%>0n~ zD7P+P>6kVYn=%tb4lW)P8&?Vdeq49Mm; zx8)qq;LKPHqxdk~|Ae56J!g@dw#@w#f$t!KzKW1oL&wx(Ltw&1Qo}SU_nm7+r zk>{0TjKwc&VmAbfgJBMLoMis**EA>N(Ky>VcZq{0wAw-A!5Y$=xX#wEqa9aY8h|IZjI}q5_k%v!~x3 z$kIFTqJT&~ENa{=IY@(#oi?12KM3!?Dl=#-kdGP{TeF6BB?VQmR3M=_tZ<$I$$72qFfj zLXZ){^LM4jGg>Enc^K@Z3br7Qp#BJMhR7?1HiU@d?H2;Mk}AiM-bG0gr}m-$2Ad5O zmy(=j5rJ8egX{?d&V~s{S%li*!Ss;nNRUANh7IJ$n~^%8o(*;i<#ZqxnH69EjZt4h z;{IC!P;Vs(OFb%-2%N>z3L_S2fC29hBaUj0c8HcD{+==zE3|7MYJ#e0f=?NJ6h2}c zuG%WXETRoU0CZwP(ZyP-#Wel2JS1>YHBv&7&MNO;R66owbm3VT0GC1h2!06Rmay7L z2!E8FH^97zu@T&LABK*E$t8#>!B4Bf^rn4J2mnJ9*(mW9eHgeHl7I>@0E#>@C>?7i z3M@*}T$2#Ie|6jl?iW68$Sl@uvT^El8;V~vIVx&f%Cc3Qpci0I`rx;f^+ZrPm8}g+ zTW|ect)hA?lCTI>EfZC}rr)4#>dB$7Z(ef$^hK(aPa)t(39nh4B}Y9}FLa=Rj9?1_ z1{Wr(N?UHv$XAf#u%v29R2v^_^98F30)279PG(B*Fihzh(Q{J8SAI>VrO22+UNs9W z^;WwSElj;D8DG&CSBn|8+mj`payrhX8{E5)DYE=BB@^e^mCZ0OSC5*noHFHgd5;Ya zaDk%S{A=u3%>XgUcj%XoV`G9lLh{;xhF1TGoo3FB0)z$EDH$l~Q?7~l%;Wd?H zo!0}ABy;8|4sRoHWG1!}d-}3bE{E~=+-kqfF7r`Vvn5QFY+^$o5<8+BXp9kC+R@!` z@73YQP}^V-FLjiGL}77`gfET6cuSw5HsxSzp*&7kyL8LQ$Yhd^`034XV>8}i+(;(h zFsEC~X_{*{&hz}+96H0K#lg$=5r9D)4ATaGZkLc*Q7VauOU*@B zHMGk^H@R8t-NvO|7iqlF7@I-tlQI5W`S$0ZHG#$fLt652_22nf8{{d(M(rkDcBWH% zNtFumCRT?>@jbM%$~{1vWUJmXEwT+IYhXHcInBSnA;$g_96s$`;{iiulif}KDx-v> zE8BR>KBSYJuHMoUp@oO}x~)z1Skip@2FWHI9{_szQbW}Skm-X_hSqg$C}V}Xjjn41 zJFyl~%+ssJ zdd5D?34ky+FZ18f1?Z}qL_8*TTrw@_l$u0pC>musCN9R&oUO4QkF0Oc`aibgI(2Ep zHJ7ofJzzHdAs_$J*>GG*_lt@~{Z7fT&9!XxPcBs_*{8~+x1skmvs^Y? zV#+Ws$lBBN@({1RlyL3R*t#k8=~*yKj@hVs+03ot+8fNh z?UE-|@xU>Ue98Fol{J^K6|NTvnLl7g*@n;xxAkQqGkLm1yB4NR!c5omv}jes^qcee z7HGMt^IEShmvz`v_v^f^W?^E?!5UM(ee)Kt@d3gQym26l!E=N3Pgj=frbhWMB9cZz!cO#ZkhX(%&mRsM&x@W2$F(ZjX2vniNU-{rf` z=?}n<=gNbezRsw=i!n!xu+oK*t=Tr*niR+}FPvH<`Fo~E1sIScdCEpq)Q5)UmX3Ai zM(MbC#~8>m;XZ>d+Ui zFarL7ujvpSXzE8r#VqGJ_Zsf@o2gfZ@rJP=QJCMe*3s;Vt=_rM{DVnB_CfdiWt>Yj zV;)i!-zOQAJ?7OaT;uYSAIZ_h9zUFzD|DM%l}L4z$HalvqrTjH2Ddvy36r~F#8T(d z@hMvMDF>11OcC5cU7(+rNPCg|{Ke=QWBz6R#lg((JLu@ucdV!f;bqZYJe$|RByC90 zg86ef7f-bk`Q#u6xLZ=9N zK&lo=akFG!I(h=+2!JgxshUFsjUC1DY-0R=?0h7;?D|hmZeZ;*8UEsAJvuNj{Qt|z zF2AfToh<$rl{d5|?A9dFJ8x;=6Mn=4&JDR3G=EjY3>lk8I@*n>MPs0a`<5mq|F8Ah;f#cm36+9wiX`&&fjc9%vSj1h>$HbH!o%G zLLZH`i8}aw-8|*YizJ2)mxk^h&UTNu@X#OhrYG|ABKUkm=cse@Z7Qi5k9-~^z6kmv zJ1g0eFJhFwNE5xRe!j3+cS?p|c8_&%Tz}p?$pj%u*;U>&Ms7H}tTt5)VPJkxQ)`=3 z-^9ZOa=3>-sdBV$;lqxO@SFz;Y%<;5>KLk*+;B$gf~xNuCUn2DrU|tv_y6F@lUt3bttVEw~?a1J%F!e z`ZHaO=ARWIj14{qogTUW5o?&>D0qc2gw5s2A zx^y-vt`QTacGIL0#1w@Q_|^EdzWO&LOARE>@xne>;amkqd`s4TY91i8__p41HS0UL zes`>-Ro_70T&m9C89Hgy*7foA^Pp}|o+9pwc>z*|=HDXRF93o9Ua>Ke4JHgCJmQ~S z*_&^k*E_+;Q-ZUXA?oTOhg?KkLfD2q%1~YvG`?EDtDOARJra}YfXIN$n5t;sfyln5 zFJ~bxqK12_BCf-sr6uQIj$$Fs9_}tqo_9NESK*9;I=Xr~M3?Bgbf(0M1`nWhA#ao< zdED4PWnYT3(fNx+VAF5V$REP|DR{%I65w4v>~p<_k2+!ky-)Gm04Bl_e)uKLgmiZ2 zK1(xXscRkr181iIt4ZVOoTL!7v>*j+4@Y5k|D%FWyou(;+*&zx!_n)Haijv&o@iJ| z;k%s|hia&foV{E9#&RJhKI-KBnI0aPxqnrQOi<%ftd9axT7K0M49Bmbk z8rRUKAj#@q?G^+JoOg}j!1tb(7^g_5KqnOQP~}}rZW0*v0pKs=;V2TWMfmDg;1AS~ za26==WS}r}H-{QdwMe%gXrUjr7EA@q0Q`?AbFe=eC732SGa!%ncO}>jL{7MnU>{Tt z!vnJ+%429eST}?sMrgc*@)H7=1-!7RFckL>8Dy8EJ0K+)YcWcvkUQWvHkdjXFG&M} zQWX@%RZ1Zks{1sQG&@)Q2v|%Z*e`go(8OtiRIA%u9T`IqwAc|wsC+K237SZP1cH&O zs3po zHH52&U?`~Kh;rl)+7`_y!}>AONtt?pP#F|G-+9^b(B7(Xgq?eWT*`y?GK*67V?O)g zH{1Qui+y(%;J&yC8^Iy;h0Wm6b(~23K zyIBPZ!qaMAPuY-vcTKkjg;$nTw)Szuk~4~842+A6$-SFxk5*dKgVYnjO5>LIz;DAr z`q*zo6@c34pz=(3AN-e5|J?iF^H@YUds{go3^4|Bx){^*rgD$EX#ZuC9@mhi!3}cuwfq8iR`2a$Hs(F21M5om!V^e?}_XH(QrjTSCNF z-thrBOipcst0q1J;Bx=+CPW7RH$vdMT@bjNOPi~ z)~2>V3H8qCsv>;4r<--gz~B^QaRMrdt##BcpY!m-ZjO68=rpj3+rTLY$f{mU1kNRvhRSVn{A5OEVZG_ zYdKu!dN%MP@9~&E+$vnaM-WX2v*VAQc$qz1m?bbvxkHpXgN$fn*rt@LHML*Z1zuct z2MNe;8Nyf*z5!(RdGpT2e{>1r&|@?n&92JBxSAhtPg$F^9W~D27LTs2^)tibpXZgp zy54e?1@W(qF^)NUTrG5P`zqj2wU0vz;ZRm}#3cWNQHGkg$M1?YJ=Yd8K zM4Gq^?QI`)dvX{uGO0~=ALeLpeCaVDZa0BXuG;_F>PqGs2bwr)DiHo)XCIHJv=rFG}GCcw~pZ{dXky`t&Q(92Le3e=V$(+qDOuUg`b7BYD*k06}V{A|_Bc-5)y{=7)>fyl9R|~C_7*+v-9WulBYvZ`) z`6Sj6Z8eFtBV)hWHFgOajLZjDzZ15wz`wOYREGN5H?iQnJVK0#A?r;m?gJ*Q_#B@` z#dX`PllgE~0ZzlGb^@N1C})r4@wpS{we)dkn`{C%;pXlu6_Q&fq>n5n-3?AXJjad( ztJ+7LIu>HN8{5r#ZO(c`NGMM{c|oADP(n(r{*Blbi#xU&*B&1?pNCD0Ho=S2X=gQ+ zjV6*#widD;ROngFC0&Mc`{ zHp5f1dAkdj;$sxW)do^(j2{=YZ3f@*t?o)tSx2UA&acnPx`~}MOI^Z7*$ee|8$>(+ zCr&H*g>g3un__*X?|M*|sIXw?+PlPVjP})PnctYoCr{5C>kbj&%+L3T@-^1Bi94nY zyX?GyG04@sF)Dp|t)uMb2~{5DRKkgw?aYHse~7p zH1~(v#@)Y{?{lw2{|UhRXIBL&&|qLMm|$Qy{{g_xmUb)-zwC`ne|`CjC282&uS%kR zTP!Bl4kjm`$aLP`#{Skr5Ui%Cq8Y7efVKB;@h9oU(pKb_2NLnla^3AXo4vKG z67Bh?P}^I5-8#jO8KWBb=0jRW ze^jD>O2bFsNPR-X8W&Orw49(67Zb;n(IgY=7V**+|5``zdo5WB46lW<=^GzlydCTh zY}V&NN=Ncw*u;G%y2vU5J?|fI-T8F-hTZRJ`v}cYcM2eMW{t8ISW+af&cUiv1T7rR zcE#X$C_`zV4^rKh!ZSGvW7O~xPl>5ZLk6|&7H~<<9mDaMG^K6mgennIUlL01R>~RL zRD*WRWTRhbg;F1zL_cDJfbibt;0cm~8XZsTKOADb=wWf2N$91pCvR2K_d_$eAqs_V z6<;nvjyhC!w1Uz(dJD>p{YC)epxUxwKl;b`-#ABic;56WGI0wXG{a<>U?`+@PV~r| zIl_o{-_}s{faM~by3bhkzgw@$cwY>oB&JUUd#V;4mQP}`E);Qog32_um(lgZDuzSNkL1%jtD^`5?16|_ zzTC&|B2-vaklRR&TQ$F1X@uI%i<*PF`vSbqY4JXEl|XX0c=Je+#p+#9ES5!tLfnZl zLQO+!`9bf7Se4FgtxZxqukVVv=k0-Q`Kss4`!Blr;NNTY)vr$OSnerJF%oB1<#gHZ& zNPr7^bMDahi+&3ARPSsWtctbf&EciKpwq*$L3z>$HU9Fr(d{n_u;*sGotOKp`^3yE zuAuv6Z~sQPjdjha8gUe#pS>Lv-zbKw58IYSa|`dQ=Rp?=gc7~PG_=Va-iF|2xxYq( z$``Gk)XF%fhBnYA`S6P{vV8@z<-A{>y|Y&g z9Sm_=HcJ2F6-jo(`61*rf59ur8Ck!4U!)oN+U0*vcFK*Ko0_2r)jrAWvI*|jHNLZl zO|ds1L`Ab*AzcNIm{rEe^9bx%xYnbJ+3M=5aBYZKvmv@hK`%ktIm-U_s5r@L+ieY^GGvyCoYrKw zOB%C9aF(NhcGB;sicZ~&>4p#%0jzjfEsG}~{X5?w^;(T0c zYMd7~q`QEBDJiH@cc~RP%=88xiFeMc+k_l1jOpbEiV}29C7t(%9FBeVY?8?!;tJ$4 z=#rBxV{P;YkHf{;os*NBmAu!3NX#`@V=8B-@ty*1bcMc8QR<)tO1(I#=+NI3{q=+^ zWf~*Ca4}A%Xm(4Lhq zn+!;wqGLP3dA6b8EE@Jz(tYaZ*joxOP2|mefLNglmzZf|vBTry3PvAXRrt74EFQS!kbbX7V-w}T_NYZZCMmS+24D5;?2R1$b2}?l zKC|8wMtB+1VQBivDa!#>__&j;ND6|a_;COuEnC45(;cRmsrhT`SlrXm)9g3c`CRlu zVg*?~ad9A;2@%NaNb0gAA13q0+1C9EZ4LWY!?dVIz)Ag_V8 zHQEL8AZ>`^pIm0J^QzH-rW6lWTr(Hga3=Lr2;&7F7WFObAZi&E&sg@GR!)JkCtHM8 z*gy3ze%iL_dW`GFjY*Fd4i$p(y2-u3BomZrdlgndq^nh(BI6GX49h;4Er}hWHZG>| zdQn|)kGmR08G^}IFZ`P0&n%UTjHBo`R;l_`$GUVo$~a$8XqRh$d0aUUrQ0nHC)OL|muU~={RFVY?0{)9tv+IhE6K-r$e4`r zzI4)J{xu&d!#Wv%FsO4iDXU=6Q%j2_WcI8h}89aapg1tm!CVeTS*u}R#A?Qlz1fFggp2|BvOX@U*PvJKIVyh7H zvjZ;!Va?1LiZQ07mCwL0wBrD(blhYOuY8#aB$ z$+)MmYWZIuTYXv)?KqhBSq%@ssR%jTi)YNf9Fxsknp*U%%$`H4zHGx*M>OWazCKF%KWQ^81gIf z{CdOFJauPm25vwOC(B*str?pbb5Zr661z4<=|#^?`XgxsXj`@i7st+hdoD&3(`T*m zY|ckrM*KB*fjjRIKKqOEQk>QAJ6U2wH#+=X1T$DPiK9U$xm7L@R2C&pm`%C~zvk!0 zpg-=M_^UPVEAn)^p5gnj+9T~;vrFIq7+Hmozvgb+b>xM9jN_!^oATQ!5Ivhb^+D=y z@;Gdn79XagI}(dnzFYD7g&U5~n*ne90vjk{#2rtmRmSaseSUPyrJ*`#85Div8yy9q z1_pD*=gcvRM;5-6(wzRZe|^E&#J9!(x=^ptqWaB3o+g4EJ@kw^^lH>~+r{SwGj#Et zg}ZbL@uwXy5YRIC|5A$fCU(}2HvdtIaY|Ydi|i<#dn%fy+Mlyg_La??r@=*iCK(Y( zGbg^*@_(}Jz%>x5W6HUnJ7d5H{y^zSOh|f{?(T8MQPxp$B3#Tq zarO`MDz9C6V~vDqQO#dqpJTaFDpHASR?x&rMj%V6d8NumPl0<-%&H^E0-5?1)Z@7N zj`9*OG+jgTSi=v$_%)q4fupc(&>V`1MfIzHZ`j!lD0mY4SelAh{PAkWa?4sU7%$N^ zUv{7tQNvASe>`dmCEhA$1`g3${5f%&w|s4Pg`x)7U-*c6jvvs2#lnlem{2GOCQVAD zV~!0TjGuSfmASbp*(J*7}yIgyl!Rvxpt^%m+&?;t7l$u}&b)zk zH4#i@HLjpqk}E39jR>g{k6a!5l(>?5jr%CPDL~9Tow?>}C!?2{&{9&=OMWCn>R?xF=xY8=(Fe*QoB%%BfJp)%>iTK-4_p zduzs_95?wg*Yly-s}8RY@YK&=(8|t|dRP-a_9PC`?}#(Q`38MK@emLy=SvUUlWBX} zaN))6VSqJ3ydggpy0WcEye5J|mtzkFr(qv^kkhBzrHNW28T;HgBa1{91ZjGg!`G=D z3T7mZecPpH4^S-f`tz)=5AEEs>ZQ(C+1n)hJRxDReev!rAKk&-Z-=xhQlD4OMn8ET z1NBT-`-3tJ1rY(?$eLLuPtVP|?hC-zo>&!3dCfhHpCZuc3wqs+>ptGVTjw^b(=f4% zm39YIvo;Ob=cq&ip*>Ea6Cm5OT_)KiaKxg}J}Cy!?sm(d2ER~PpdxwW_oG74MQ5N> z!J&2DReV%0Z^GwXp){MmtCT1+vG2VhF8UVze5I2?Ck%sF^i5g+rSkg$v0Y=Ld#k#| zs|(PKS%@K;vpZk#ubN_=;gA&gdNfuG;o-cFmqyK5ngliEAl1@@q)7H5oqY8R;7Pu^ zjurKG0_*5<^P1JKV~}I3*koAi8c&4Oo>|_jNUt0VYSzqDNim@bNla(73VVSo#rD|G*c`cU?*e|C-fqC}zyJY-82p)S5AgV6Z*TcmkZ(;b z`;?}?f_#sM;V+J1=$w=Brty*#PQ}bVU@Rp`XE0(6L*5|_fTm90jXj(>L;JM)&|q`v z@LF!x^r%x4LT1&@iz*gh!*d;bb8r~=#pJv${QLz6z9+JlsJ~{GH`K?Lng%{ryQN0U zby<+gLD+orcGOU&bmwPoETG;Red@N!5e4k-wR^XGbLP_Vj2Rltt^3A=7f|QePk3G=@U6f*ym13$8VBRSx^ z+&TuQnE>0{Mu>eG34Z56X>PaeF1IeZ8-?Ej&-eU+A}me4Q|GwLwj6jb-V{b0qjJCm zJ#@eCF8Wbms$q~V7^o!ax5a`nY+H2}UeE&yYNB$%pX2Bk6>qk01px079 zM`P$H=DU1ZT)D$w@Or()K%Ft#g>ON!^0xu*+}{>8N65+yfL+(;m!UbT`JKonyHb=S za6^5=qJ1k2@T(#;?ufVG);H(xxFHAwSPq5VYDoIAu7Gb>zY9KWSgb;Bf|FnSHrlZI z#;TE}=qgQ7*tf7RVSjbM2WIsD&ik27A9-w-Fk^HDYa8gP>WplQ?-yPF@%l0NlNUV> zUg{5T4}Z_Bybl3aWcGGeXPV%Qf$E^~=roz@k)5XAF4tuAaBwnUWLx;z*ZpK$)vsTB z!hZ!Ff78N&=_eCO@be>VZott_jd*nI6HYCVqQ;6b+crY}MKG*^uWmO)JZvkVc7t!@ zCP1FaWyChi6EtOE5AKFiy^hqVVc`g;wbmSd1Rbm7=Vdq+=IW(r0Ph3r3GSw|am-I! ze5K(hZ9QjRV%Z@bf0qDVpbK(sU;?Iw-`s{jJ)eaytUoseynYDVJ@;k2O93-a+#-982nZq4n}+%(pugj z)E}mP+l_%DA9N&h2GwBJSoYR&oe>Gfv$iugo_-h4wFg=Umyu`*bt{?FOlZf}1Xx1c zu#Ro!C2)?d#X@@z%hFD9FZDm0LF?%%e4l!d_8Fxu-!=KGCEqpWe{HyY*W|ALXVdJv zmUmzEs?~WW?o}NB0A-dNm&=pLEH z`>)L!nuo?{Jt%-$;LE4tmz1{)1cK_RK%#@Ogxi`yG7=_61!S{$rI!s&-ns_bI$?&|7P@78Oi6k@@DOvv-A}fthV7 z6W?Gu(=gZ`cynE$C%;^sg;fqi(!vi^&Boc~-}lt&_0ODx#vGqk*7$KEXx&P+ z^N_6dT@{arDO?}128mgub#egFf|h&X!Dqw?Daq6dD{LE~0!O zr4Eolf?{_BDO8Nkoa0P_KiWo)pCo|z*&CAHB}*uOfRB_?~KdBPrnPZO3)!WM~>q6&41v=Q3l3Zp)BrM8qE4 zdJB8qTK&KBDyX*wGP=$ws7Px%^HMAgG-4cN)ML>_lU$o*@W?-y)#$Wf{hBP~Ebi1c zf(XDC9Fz63EMexiL`Yx_r8fZ${kp%ctrn9wgp{VY`bqwVD5+2`404j-DsW$`^80Zdd10c z`o*iha-ma2ZGC`>AILE7(_|Hkco04NMnw2)PavbiFH3a5s;x?si>Hpoh}m#%)?<4j zMw>r=csklAz3|S>7G2eHUp=R}3Fy0VR#cOp@iEHvOl>wRgoG`P0RkuK^A|VA_$zQl zrP)VdQz&JyjV1cB?fQ*CRrxW(=R+9-$;Rr*&XR59ebp%)3T*bQlbX^Q0)8LkI zO)ns7{*ELe*;B`^*7AlJm+w&$2HbSy8MbPuB7iio8^&fD1yb!FKgpLlWC zV7GOaq#;}6r|&c9Aj7Xq&Wn~9o75TAA?ra+PZACi*j3pPd2jvH&~`!YbHE+i!3AjhHl3cIDS!eUz~CXFsD;9q2fqD4?^A6-&66 zMnxIxR!1GgGcaC!mY*CzIjrm(c%Hsrp3Md~HEP3QO%~3Pk6NliMt(zN8=h7TZx^?CzH_i7X`H}7AA32S`+V2o&*UBMg}@1e3cgN zcpY%HE<&L9K}Y+-CG)|hkVid7PP%N3nt?1m+0pT;DGuxr36<T&E))ppbH)hLovn)t+`R;?YjMzV{` z$#TSvK;GWucO$yiX48I-=v;^m4zWVFsL^}JHueENt$ZN1HGD04lsR{^(c&u8yxex7 zerEFss_f3_8kY^7n+SNNF>#({fnS*3%gSABLs!#({kAZS4pc|Ns8MuM)0Ke_lR1ReAa6AfBjc(RKC@6EALU#N)ld^&{cUG4fq18e^Fvn z)SUvyoGyg;B+mx$Wt&Ph%6E3i*9ojZmb!!;z9_=J|kLp56LgH~f<`3((-iGj#{39#{!@>a> zI4*^Jixh&4L6#kIQ3U0%>U0NdQV2#K{ll8%&z<{u>bJ+j<>7*owbL5~lvggAL{Z@0 zBznF}^y%o40*@Dz+HFR@jM{I+-d{H6bs}BHbXsnp36rg47@~Md_6GU2T3L3%+YFZ+?J!)9m6E znpu*%`H|OD9vdnA!ffqrdcFA4^r8&FZE0E^SL^85)!b3CwAvB>a3Uo-==f0G`IknX zx!DT3E%Z`tYN7dVdVQ*?*>2s77*^|M{x+d|)9lif@@Ha&c~s&O<)x19tmiT(7kX zDqCjSj?{HBxdBoZ6`}$25D4ZDk9#A6LFM<9k72vb?No2ze@;*0IiBHV04x`nXn$HS z0GTS^nRIJa->etKk>1kU^>csvw(QAgO37H#$%q8UWQqV?>}cB~nqa#7D1{}sot!tc zzw$QMb@l~HI68}pb)SwLkC+(qaxI01Uc#>=-mUQ7G~rhBu^!~J?LSMC8PZXrGpjLR zfp`phF6D&VVA_gBZ0amuStLI`$AKbojSaz(Ko1%b+Vdku0)o4e){ft}4iGvGYbTMh zQWI2WR`f7$KT*eqx9X{?mlJ1jISmBRU9ijtfA;p#!}?C3?flU=Xe94JT7w$T2z+SP zI4DP%aE3Es+Kf4wUXD_`pl)wMbWj|NVbE7)w=c@UA0NyEkFYJd<@q~mwg{I?7U5m| z2c0Q*-yp&O-@s-YQV$vi?UQo@cm9)5&lapK5Q5K#7p}VCTmh#fzpO^>7~oQetFcc50=!%iqj(B;ILVsg#xBW&aQVg3-z97zP=U$c5$m^g zyFCZEdXV~S6e{BUijVG#yqq7UHEc96YqTZ+l0RAT!nu_+Uw#P^o4bBcXmK$}dg;7= z?ZisrF~6i|?1%STr2$F)F-t~t&Y!c|l&w>B_-0|MrKs#Y`NB1e2bLpd!Z~=rcBoTU zqq^2&oq=qwsZ^6XjAp2Y!)&6)GT0K31>xrkMk#eeU|)V_A#+n~U7m!Ra)J);C3+t#nn0exY9%)yJIajOs?Ri%e326RvL6aLT)QV%K8ks$S$yqFR=-I; zc7Z_5A?@N>k$)!l7GCA-?I#}Yl*&|~$#_aC)-5oOBK;YuU`#^8TBOg@d%kVnZ?C9Z z^=86hP~#H;Qlobnd|3;iK0;rM`;kVFUPFlvX!1$TTHc6 zFgyc$#1GAo~?c3>@rwyv1h)P5V{BdDCrXehEp2gC>cr#*M4~-B$ z*S=&IIQAo(IY}6ozc77{i@~40Ar`x*50~@$VAJVh1g2C%m2Yg#l2L@@hn&om)v)bS zxvumLv_-)`VTb9noH5;SKnlbe)u16S{?Bc8Qg50MWRN^M>W2yhi#iMssa3@RO!ngx z_Tcd}suI*_Wl8lIe77oVSb1b51vv90X{nNKffR^8qBscExqLfV-fI;rF(QCHKm5gF!(CLIn!BM_}{drse{wk9h0GO#= zd^b}IxUIjNl*m)DwBBS#04z|&DAf6!&7mt)UO(dn1Vy91D)?EcR-G`0U3X@Fz-isC z{k2bw9OPpFmqgsa2zSKZjMLfaB|7sG-O7jSrqbIEOMz-Oix+>UI_ChcL~05cR1Nws z>@~SEKBoJ_-WYoz`M#DvCx2eV3!0jB6a=~nQ=X4cQygP7`C;8xsT&yhrq&NbSN5~JefgYVg7Q4 z@$x-rr;J^EU3oLZzg)Ip@*uln?O0U=g;<+?vQcVaM$mY?eMJM;5kGu?lq7pH$cI7L zcq2sJRGBpSVkne#&Y+DQpJkTkEartNnI*y!_>oRgHee~Di^BxZ*L@_1Ux5H?RyjZ6 zNzti<*y<3%fn>7(!29Ento2>pjtJy*>Y-JAY-Ly_e-y?MU%b1e52*v^$M79_uH2Xu zU(Z}#dc-N(O7?qTNQQBmI{Xm||70*iI%43(E)C~P&Q$442A81vK9^+-$<>T;GzlMd zYMZVeW%IE}j2wBvLaRF2^F7GC=329@Nb zm<{Bq_FNDdW&koceSk0>s!)P)2Vc6%Z5pU5x5g~!vLBKy&qhSV$B|ekYU%!%dul_W zgqbXlZN6wtP$yrkOm#P79Y@(QEi~8&deV6n7xYUj3t-T|BID6O6AwJ9jkcHk5I+v5 z4$VT#LZ{61orOa1mxAo@>$H}ynFG;1G+uS@{L^p18v?KV$!3n7=%J4DYwnpDPDlbuz zL9Q+7I6Hm`v=Mwqv>lSOK6SuMH&YIKsW8z9+{Dp1aV!|FP^#Jl{$=y17HB-_h;J4L z`8`4^!J%xQ)gZNEPRC$0%Tqt)B(~=;mq+p^?|JaZ;0VbCNlSolf5_}QtH$XUdo-CR zRBJ>Hl?*WY6o!^i7af|AT#3op2+b2sgg^Z-n~|ItgV}cIxt!T7)mnplv0d-EpRLyT z`c_plh#?i%n?aLUP?F;BA|h_uPt9*>eDA`~ca+zb5NUBMNkc(yH`f-q#>jmW#JNSr zqE31vBgVpz>*>I?8iRR*csPx$ipDo8ZGfI%9;i4xj1La3i0#jDU|15MJs_?YDj#-S z;NhFg=@RUV1sXiZjOte1>-0FEy~8^N1Frd+o%>3|<~tKQsIBT0Gea98Y4(I;ylXhG ztpx&fo*jE4Wjr{VTC}_qpcXt)U+MHKNMAw!R9>@DCX582KtOG9KtQN}bD6X^GqwNE zWNN9h_g@Z^FBvinW)7755a{x04wlnXhy;*4UXa*Ia;R#3+PdY&=qF`UlQQ1cmIm1L zjf$Mb^4-THDX!MW{cR0Dz4q(8`7owz#!n*Bcvs-aR@x83&V){UmsxT`HmPWzgPRx) zdsr;D;qipLB#KZ$D{9T$=X}-!yQ}-t)kx|kqco!nJHEXoV&dLwfK3@AL*v~CN@QIq zSmud)0VU?k=iPp0SgVLcYX-Ssjw`30bqZ267r3$VTRdBP`w%RChvt|aY&@$n6=s^B zu9nDnAg+g^(<5BeWaaTK;OlmAIrGkh_yw#M5+$=CiIlT3jZh!{q@YKZM{PAF4XQ!z z&ZLKc9$QTe185sTFMpYW3xwVP`i8YUp%<}0+p?MhHUD@ez&yt4R=)A#A}x?FN3p`x zi83#_CDa290`J=4Z@g{3sGg#YF21tBpIU;@6!T4Hx|Oic*2;U_|D(7$Y)6=k6-q+VuRFkB_{A&as5JdJGy>N{#ig{gF&L@O*KunI) zZh-fQ$+Kt%SGAhSG4E;zy7(5#i$v7DF}5whd*m`;A=r#-- z!g(=~9zx+F0qj@?fKjvE~BK_B(0*uKM> z_d!D^vyCm_qeNdz)dy?_xnHf~R<{fAerZ4sTQ;B7yX?fq z?7q=G7utUN*6RRqd7(S4@v>mS$R(LvPZ(W{DhRbeq&>6tnhp6@1zXuiGvc z8Oc!p!Qp|&_@L!be_NRI51A^S0C<^l%qa2Of|g58$~kQ#hEeo&)!YSWD5V&hGTayO z6GjDdm%D1is{$Z5x5C{yQCZ51=tVKDlMHKtOOybdvLpHWa=84xsu#rueK_PZk9&A4 z`SP>d=2Kmdw+$E1nc^EAu`LF|t(nDcwm6-7owf~zQfAghGI?s(0l|*-2NU&>EBd6y zmByn+_-bA+82A3C`po;wn{tn({cDY`Hkc~=V)c>WMpTrXJKgMU}WH6{g*5H zsJf*+)*#|vc{M5zKNfX>MV?#@?i5c#4{VdI6fBNr5&^WHO2Ha z1{9r|Yc;Gw=G5eF?ADawm9(dBgD?}Qqh zbZ(K5_J};@ZT}Pb`8AyZF*6H#DND9Dl+ZD{q#`+ zkKTKT-|y@AoeMdx`{0FHWia=~eAYQnNJi%*{4_j-@tjxY8rO$<0baeWxabDnINZpR z9VmrS0c9Q@-BRHkNJL?~P~2wPW}!csIS#p8GSDf?cxHJzM1kWVZdCfQBDOP_9P#t&OcCj z4=a21;4B$@$bcx^3(Ds=c8_U){BV!{Dk!OPO?mlgp3ahLyOaNuIPcj?6*O%ns?!(` zp6=t(*JCK~5%jK&^zD&&3$e3pZUv(tw8;qcE>7Mas+)ErP2JSp{H=cM*{bA0i^?9X z+o2*S(W8D_x{wQ?P;CbEepHgwcsbAoX);L{@nf7IK%NW)Y|n2Gl?*0P+fxIjUp{_a z2s&MVnK}7}d&gS^-_OR@-`d$ zm(6uAT6_jrcj(mqi&KT|I8h6K4W_A}9=)IK`0;l4v1qN%rXiJ#@{>_=Y-*7UR1`FR zvVY8cSDf1szHJKm&`tC4@{(k9R?TdQsZhlYdqHE zu$9{jJs=)Z24qQgWFN z@vL{Z!dODd`S?HV9nA(ep21K#jsrDU`4d5~3-oV_5J@nkD z$Sr*nq@99D5M{9~1ef78hQso+4k&Mu>A|f`SWc|*X_s)XI@WD?u)ZE8; zae?yIIyY(hb*KY|i?@afe(9_+A7->Waq3XI9Xh=^5If%3Z=Ij(yuH2<bo?CX1S_v-dA2qX^i>HEZB&C@$>i)^y9 z)$oSjIWq*tULdOr1c_*bSbJvWGA2od1iaD4Mqq;s0lFWVo|YYi!BS%=GH#S5WyqSi z^`t)MSq~pLk;5t%7O655)=XpoRnIk#b1yd#j$nRQu*jYovQI7z2;^lh13W%Ek`#87 zH)-QgCzD{ty>v|neuv$ZaOmu%JE@Ny2FF2VA0=k|mR7gfdK`9&o#gfCS6$qtI1TC% zW=&o(WT^?5YMf5~z-2tVJDKJc8Yhl2#j2bnD~INsk6;$r;wO}Zxg?Z>K-|^kXru|- zxwnPHDZU7kpmo?5^wU0`B9%BkT$iW&+b7pOaaqwMVmA`(B1DWSd);0gT3!)$B-L~V z*9Chn;$9NBB6?oTM3si6Vm8jZsU`UQXO?W6gD?Z=x-dC%l>Klqc1Y<&ay>ChWXE~n3n>&l@7;ASD{>k+Fo9%xS3pq z*XRzt9ZT9Y`Eir$sXMJz(9LN%`*oZzudN#`ni4UPw%p#D$l}+}!IwnPmNe-;cC>0s z&E{+G`NwW@Z_O_O6Zw=|S98LCuf>Ts1t^jGXEi$BY63GDgAkY@5uD^8hVpN4hq^P} z38S-}F*TQWoJA3C)fbODM@`Y%WSHLMG^QtCr5qQHX?pvzEi4P-)khP8){04^FM=lI zSEDw%T=$kw|MolSy!#`vq@o5B!&$i zi4lx)rj0~DOij6OY=e$^&OoG)DI*&R!0`}3@-mzrbp!5=7DY;Z$WJ9vcZW zc|%bzxRviHEl;Avk(KPIsZvT$YeLH%SCueTd#NaDXWzB@CQul+UOw}+c9K_*w)<)e zCPKMDk~L3`jjlJ20h8m(g7JtVK8ez0l)k#hR)sJz?R%wy!mL&8@;y8KqkmzQBB-vJ zR85>m|I(r6%I#R-N@w5>W|TepqotdF^h=5S(AD94S)y|VQnG1qvN4}Tg56#! z_ome-nLS2Svw0DcbM1(x#svO zD#L*9Njpv<*2wKh=9JgG5U)4M6qvD!2|T@6I-O%*XD6T{mF~oG1G*AV>%n)O&{X=O zVF!CA_$8|pSI3-|Jv1K6*pfAm>s(QE7HFjQHrzp)CL&s6_C{Kl#(NFZd!u6kS4S-7 zQ8*+Z%*-M-jofSEqsZWc#s20=HPc$Lzs2#C2(4Qk#*xrRFfl%x==Rn5nb%?Ls!EBB zG*N0R6>J)32?MEn_GBfh^m2EzL1z;0A`~o76A!Z(d_wVkMUA_!0d2lxLNZ!8+^}tI zs5lxp4f+xy5LY}pm)xZ;%c|^ss%3oDa_%G~D#N9uWP-{pyNuIWuASXCRQqq@f>WYV z0x6eDm^{!=N8^I?65#rcQ1F!vM z6?N6acDBGqW`^k?@WCNBHL6Iesc>#!F!$wi1`t;6MY*0X+2x_#AT9%Hxb&Koa#h=t z2R6+Mf5)^z7%7JD=B`~{u5oY5)4bocl9tY-fyR0Bo`-zQ)dP$Et43A<^S)ht3@IPS zdh5Ak0LqgTYv{D7-+n!=`P7J7Kj+V8o-{iWq`PO|w&l{IRK^F%jS^2gcdJv^q$eK@ zHy`r}77FrRh?Jj|Jw)o`p0o+}YiWwJ@ZZl>Ji}Q%7@_*1$whF7(2gQ{uNR{^}gMQ{D6vnSx~+?91*(lua9LPbmNla7trxF&8 zE*b(|C>9WY?O}J5Fd<47C+(s39!Lfqefj@!$g#1?HS>s%Ya}#S|y_hRADe=RV#_U zDa9zt238I6TGnwqr%Z2WX9*OOZW;_5IBmq@PJthXxG_c1St!DlMpn6IM`Ju{K*mvS zejHm=y^IZD@?Sed6Rk(pzc+cA!J0^*7Ftf^DH8g|7d{Z^!B@m_^h5y#Ku)3ZuylPU ziO$F)^7w=tZw0MDi$qxXJL+J9^PiD3CzQePsnJ}$LsKqFX>nUb7& zx^-F8kCL%9=7&5lU;GvK!AlXT5$%4Mjy3mut~_@{YH0`s0vn_9z;#*efYin(kLQ%q zPS)w|se&~TlvFAdO{9S&^G!N|)q!AeNtPt*G|%$lhQwLA(>r#f|Mt)U{i(axVZGC1 zV^nLc4#=ZND>T$N-TbnxmqN}snlmXg1Y=I=pqyD->Z9w&qkUY{5eCLZ^5A{s1q<)5 zftufy)absz!FmG4`$pzNj8S4MBUrXWYMP8D89_85`R#JijW{zSeyDHhBb0?NQ}%`|TvG?J8KaPQ5T1Q}u#V9&1#1kW@)#ii$Uj z5YvUIX z=yec%^;vw-CZ_}Gb^9T%xsIk~hPBv42YBNgKy#G>>dbVh?x)Dy{J$P2DRCk55dy=; zq%i7OE^EM0BE}BRYv4z;$bm~dJ@yd9!<*_NYk1QO^H*fOKwt|)^y*-S%aE6&6upS~ zCq|iKZOfY&JqosQ9|3X6P7S15Dev%WkYal*?!*t3AcbN#DhUEUseGihi_u=w_UP*% zt{lplDcBDcSfJ3C4|F`x#ez97^aLhvyKP|C=347i;%@#PS}7|eqJ?muQ0Q^eFx4?p zua@5f)~;w`!Va-zCp zqqDQTLp4KtXSq}o%YD)65rUi z1Q^>d0WYM#8QuRf51Cq90qjCj5j+wgUl0VZ9#DHpoD*Ptg~5G;(G$skCepSxw{rcs zsvNmaJ#Ba9kftvwLT{;>O@^mKWr(1mzZWS|-bPXWDje4UlBA3>OXLyHEWoohk|!=L zN^`3jNd}WXG+>q=P248bN}@Ph*I)#ihnTP-o>k|SwGnDuHkL@ta?^-&AqW}aGYQ)5 zmAn1eeorqFy&i}I-)A+Oe^iF1734mz;kf0taJzyABn?+IWHqhX?@r)8!!G_`l2 zF|{(bru(9#C@LebKDxq5lRX{?yrS z4wwPi2dq{h__ug~eXb8Spc?-KloC<|#5_{`@?Jc+5xf2n2p}LdcpxA^mH$(6eR=>1 zcK?YcFC-u%FZiC-Q81;d10YxdUVr5Q`FF|n2_gDtmWrs5kmP$51B4n5z#Iw04S13N zn*-SA`Va#e@t?#pvU0F<)v>WQwQ{ikZ%r3T;T{dRbpkFm5D@7f)TIA|>R@f7V`1cE zWbxmS=fB_;wgHzH9T3I?`48moZzP?Lj;WQYgN_bhq`a>wN4r1583*73xV;BFefm#L z>GVxaSd8tAZ2t>jc+bR`8yE;^1t7s+4+Z}&fc~KOC*VJi2=8TBS0m@)0c7p#Cizz& zzTb%NhQAU2)9QdOZ)d9S=gMiOiX=;*_M*||S^z+au>|6Mk^zxIFy;eRfG ze2-dB&{J;*I3L~uTJ^6W+W#)OKBad53-ymRivgQs1hfs%2f*vE2rK_Cxjxx|_WqAR z7N-B#CDK_bZA<{vstV9|0E6N`CD&*19pwK30oL;Wa-lSz*hF&y0~hRnHO^1(zsX{4 zXli9*@1W;kWT|KH)zr%9zo0wfZF*>`Tn~AR7LpTj1Lw<&J9QL{`}`Le-Qp>_1^p5MZnfG zP6;@F9^hL1*#eBoe>>XI!0h)D-S>>^FTk#PfUbGS{Jsv68GkU$?fzltegaLnX9rw| zX+S;xl!Cb79pN9_VPr{chKUmhD8T)_6cNpTFdUr!L5j>TKQR81V(NcMaeecS@Q+ep z3Qf)#kO2W5$-Y-Yx(~k@Ci;v_42=IEhF9@x1S>#{MSvK84%J(N5C0je|3dtu9IzBq zRY`zH6gbxR5IvILkbh+&{YOX_7Ka`x;OGSPRm_%pfI`z|_g zp`7v&@SK1n{I99K-!+j8{1av1YG-O;VQTR2fUECGug&EYW`J8nB*S|h7##g4$;8gc z$o!u$@AJd{7KkGCPt2d$V&9ANKIPbN4qpB{&ie#p?@{lwHT*`=R{n|ld+vt!l=rc0 ze^ZoO-ckOHZ2KPcJ|@_2kV^mGL4QODdk=XZjO90kcJQF4 z$HDiU_p7Uab2exHb!SC`px-% z{x{CwU6S65@_y3&H)7@HH{!od!M`WHHwyhG1p$BjkKX*lMD!l<{`cK)#2ff;#P45w ZvJ#*GB@IaU2l!(Fcn<7C03HN@{y(7kPj~eq{d8D%^FX= znF`XtASeI;01yBfpj`^Y3w}Z9hyVa=cmMz-|DGD#+t@o9+8WX_(6P`l)0tR0yU<$N znc33|s;WrHD=E{tc(|BmaK{l#I*omQp_uMsGOvfBg*^}ZHsaejW%cl8ItH7lHd1xr zO-xmjlv$h;3YnseuAIBpqj#N&2d>!FW z@ax{#RF1(tftyJw{2Z6d9iY0`ty0cactY#p2s7D zw()Rr<5c-X<@5ZGuJ2bu*3rSDYmZ$-7Gl@5B(-J7KM8+e;4_5lT@tnGhSANc%jUcb zwnnLYK5!Xx4nET|$rhxBycLr3_{X(~tOZWB^~tSDxUNmd+9j=rm8V@3bI%;UA-aHR zE9mEf=>aFl6NXtE_#*@tBsj2{D-e=S@`rz@MZ3IQ?=Go{CTxwKHX47 zqlWUCg5Env-Ok)K$7Kg~)O@NEzk3UhcGsk=_OVj}jM)Ub?cPg!iWsYktY(JJX1q#` zZRgx>enVz!H*&GdY#dKU@42?ATR0cL5gRx9v80^GM@fvj0Z}yUitS}LCUb@^W;Slk z?TUe|h-W{%bh)J(>H9q_J}1M>w(Dt%ui=`GjgUhPprI&4-Is~sW8YR zziIeXu#K8%v0>KoxT{Ww-9&mV&U4{;){QJ{1VLx9)24SulIbN)jW{*r=9@6FP&-XF zvt~4eE(>cfBJ1_2gs_YCyrO4>HZ}fWm9Cb`DYXn^!=A<_Zzl$Fd!+1Y5ml@4KCA1! ztxWk)^SqVyYUQ#b^^fOP%=x8}qNw~f??&cMSFA-8v5)FruB5FjvI%AOC&_kq!gLp2_CtTcVRBk;&GcNEM0Y&exK8dp zth^gX4jaRm*Y54NOj3FZJl)7uOL+`Ay(Y)sEeoMWRg9*M%c~gH5W<9$j$HpFdR}Wn zthdJnG+^zDYA#390kFT=J143p;y?hmyFJR}!yMeNY;{YU^TQ)af{`dS)Dp2$z{~L9xP}E>&Bu@O*!}H^yd7A4lzCo$V_Zv$(tkRRyS;1tgs9R2jEg= z&8(ZNPt_%|#pwDW)WI5F%KT9Rs~3NG^D$5Dk}&9JkTRgT`owx5bL^|YP33Z1?< z7u@#TUQaYBPF=Pn3EVHd1W$n{XlP~wc!+j7XtghVj^%R*^;xuVk}NLS)sor>Rg98l zrclahiwdBR)Gx$|y-*1v`Vn=8)pSy*)jf-QXawpS7*k~3@LYFT={X4prl z2W(3W1@}b!!(d>^frUpw?(Fl1J$Z6R-PXd{#coz)z0qLbLZs_P$v!8;@P|fZ9qVIS z)`l{K6m&?wnlgt*w2s1;{UWb?884vE#)Xjg?{tg*QOxH%ziF7im-77hk=IU?+ReBN z)mHZcrZi!o4m<9U)4GGfoH!TC~j49H8?1 zwGMilv?aw)GOB^uD<=>nA?^$108NI={0>-DA}88-*hsh{Ag%|n4~erT_6^M^>W#lE zD^b_a_}C?Ty2uXzAK60)4nsxv!=c|P^)!dWi+8T|$yXtkSD#n3-1^!W8&&lS9g66! z4cJDCT?T$XRSMdm*df|RDj*f)Ol2N zUYB~!fkp-FstH&<%e&C{)+9zJ8f8HAX`?l3gNb&s&tF0B<@DUjC`YipECM0jVkXkR zHY6RBQk5@@wVz}Q0pzx>B~o4Xx|m^es+#C@>S=buTu-WO%4v^b9rIM}xm4_}W~$42 zq^LBiwUif3FNSB5Sp)#ynBYP!?8QLq>Nl2!d4BgLMC0-a&8@VBZ9=_{apNdc#0s>M z;0z?C-5S_j>J_B}R^%IW0fI3l()bL!F@(?OTOckhiaY(J2g@jiA*R|@lpXrgSnM*; z2E!>Ju{X3g=$QQ>)`(P!!4(ti#h$=`?!Tu@+k)viom7G^S?y&O!Xe^Gy)M*wTu&(u zzIy5Fv#7{GC8uG-sC74F=Exqg#8I^XO=R8!PaE=nl6SwCx9~4276&JdoryiP+r11t zf3;5SQoi1btuL)9i>!6WQfPP}R`6TK2;03lD4y&Z+8&lehvjLlm+5IX+~VOY+;a5P zk^4^ZMGN%zakb}3bNiQSE$S1)H@>ZXjyF{W!22<Q%LeG)5+;N*kq;6i$%CkeLsS{0#CYs51p@en}cj>rLD17+`VYeonfmgh~E2e zZL=f?iWRRnBd5p&>ebe2rIK~0iTL_~bqSLY7zk6Xa>a2Sfz@1W`W91M;?| z8i>>dqAnN7L<;NzImapMsyX1)o7)gbEZ%0XJas|>w$=`HAaswKfP_jSCIJw8`C3{{0%655_xYb2@%SabZ}k&Fr$ zZTcUz#U7g%YV4@W?2P4hv$YJb+ZY$1nK+IqSdG#BO^*YoYHJb}EepN5q(0ZMd(_+J z_8N{)`HNZ28~>i(b_4M}h~#RC`T69y{M|J>OT-xpxPhMCSEm)4nL}QYb~^kJ>Jd5m zp}d=SKc^~cPN~ZTBbvLMNt#DyKwD%*MrsV23BuIH{FkaIzmocig293#s6{MGu3p73 zVs@aq1p779RAy<_59Q8Vs*4h_UPSPNS8<`#o9!y&islYRgXE-fU>njL-8!ZDS4Sqv zyJqYn8Q;9jEc+hKJ1m2wahnS})s48agM8gObDOjBebx-HIY@o)zAJ}6T8DLK5N=LiF<^I)1H{gk8{(I%z zfiyD;aZaxLzjg4IF6IDXS6G$Xnka^$wd{!p?hcW^Kd*a1Vru45QV2J(p!d~{iCQv~ zjrdKb%Xl{0aU$3&kORDc8j2TEcra1W=UUe$cwLS%r7R=dX54_|3CVk$x(Q~z*a)Dx z9$}|&u4_Yo=?$eSx6rg%^|Lxz*%r{+QX8x;Rj^ulDQS3q%6a4IQ?#A)Fic8&i?^5? zU+`fUp|Mo<*}CF{M%NN}a^`{s1AOJxX0+e7wKTa_JuN&2{=sqezlQ>m&?ow+UBKg%&$F<16f!G5nsr0E%gPRXxcY)G{0qgD8(HrW-KXOhDHWhI0$5 zk%JdE&gK-ul9VL%wlTQYPzImg@&d|{^YJk9__?cK^nk>(mA=+_^_vPFVoq4fHZ}4I z8DqtybhqD)#w-S!BnC@PW=W;XB^KPT&Fv`*h;*IBk##x|A->DV7Q28V(5)jR!d zH$1oEvG#gS4F*72Egk`z*BJj&gO0)t<3$d1&|p-T54sGxTQz->cd1axdAbyBhImceH=x$(fmPfyAGFob>N8k}GpQ z@`zJ|-_U)Rnmt671q5p;pY}#HW#Gt_!&%n!wN$5e`pOr+)|1gYGXwjK|AkIOT8wdO z=XtsDCTF?Uno`oGhM62V(G_%pGm2pHoJz=QAD_@1F_N_!*KDU9K3+NxiKpS5Ojb-W z%gkjnv6sPeBIWsg{Pa_K4T?r^;hP*{P8q+O_*qFTY;Cp=Y+Rl}%RCo^KLfT!#z=j{ z`slL`=>f|ymSAChP+gbjw=;pHR1SzEA6_|ld)5j~yFngO!h&`&u#^g)3`ue84em{r zK0Ri@1U2Jghz8w)@xM?y%dF=79wQ{E5Y?BfGgH6q?aAoQDEA$ar-Xl2*dRC4x3IwW!h2Ro=$>{g-C`FH zQH)MDvKQw~w3!kA)>7h6SPeQTjTm}4dTwY~ifU?F%cDp`2#6f9OkBwxF5v6UZ&#rmewUKQTs_lsK*BWscTW6F<#AwUFtWv(x(+Y!FvT&jl8=k-9J?`w?S@AY8p zYKY(G?NtBgFs<+B#NO|HC(Q5juINKw;XlC2rOfkkAP@k65Xk=ntjI_Ti^?gB{ufx$ zRhGBkWI*XVRpxQDDv5UGwe89nMzJQ0#Zew*BnkC^azx2$^!@BXKiiZQ5^CMMy$u?M ztt;Yf1-!ZN_VDp|`#8Tpm|~x=2^fHzPe)(s7>LHZ>1OO_^CDH{gzp2!u`$0XDrY#F z@Uqv1Ulq0%Yw`;@(s&+VVZ;#==>T4~WyO<)84z6Q17alVzZN$2-oh_}vT7DeDiFoG zg*#A+0Sm(}?{;sgiHFBh&yz2OS0&(e@*fqlF4XiCp1vVZ7*)Yt$J>DE<{cObUCjZG z9t~Sq9Y#D-*vY|uxO>^&Na~?P@VOX6KHo3~dcYi-V0{tTGmB)+e$9Ed#bHe?e?9e2 z%cZkkLWXkoaU=Fvave5UcujuZ*wp#$p6G2z9`}nQ(z0uDr#G8)()GIq((2L52Zg!S?%{oJ6}t6C)`b?< zt#123FemZEceqFE!r$gN|HgNY{h)>`(Yc^i#u0%GNt`1(p`6x;IMsyF4&ZN!0n1jP zS>ukEHh72g4d;m={%KO^rV*qFn*C}jq?o3A!S&HjA1BKeWQ1xlEwv4Dk>35lP2U|hy-U#Af!D~L#x96+JK0k zbyL1~r6o7PbVvdD;pB?@0sLnSbA4zHwW9(67;pdp5dKeaP*zk$P()Bga76ptd5dlF zC&v%;hD&+FlXS8nr`eUR$JvJ6@u;pLr?ki0oG3DwWR+xqSYYaE8~>ND3qV5Z$71nv zI?EDQ69BE>=yk&!eY}E25h=ssDXH3}GLp9emk)lnQ0FE>!?ZH;fx=>|b#TXlyuI>~ zr!te*QGv2X+!QS%qta{f+N+>|A3IE1le7d!5>LUVbELG68A zBxS;c*^YdxZbnGe`%qj}#0(MjFz5OJON=RQ(MG=A@z=pGsd}G93OeYQH1t+Igld>x zQKe)+5^GAx_=jCRY`}YiMm5EvjsHhey($V#u|T;&CQ5|1CEPOWn(p?iY=7|2Ix_z3 zZeETb4>Vk(#HCB>A`sk3&9q9!)L=L@a)wq^5AVHD^ss12A{X2I83yc
      qbmEDpQ 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 E0P%w@F#rGn diff --git a/env/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl b/env/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl deleted file mode 100644 index 6f611c17fc58f2dccb4a961d89b020df697ad5f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12457 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 diff --git a/env/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl b/env/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl deleted file mode 100644 index 43c7867224814e8c142404b19a9ebeaafd17c2a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147296 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

      8zv7L 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 z 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 Z+zvgBpnLcIdIZ=$ZMLiE-b=sk{sQuGw7viU diff --git a/env/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl b/env/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl deleted file mode 100644 index a37d282b156463491f5f44cf073944e212a6c7b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115285 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%0A8AySY5A)uULcQ!$ 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 diff --git a/env/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl b/env/share/python-wheels/ipaddr-2.2.0-py2.py3-none-any.whl deleted file mode 100644 index 2c9dfd25b4e1252b1d6203e34ceee0baba494067..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19552 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 diff --git a/env/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl b/env/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl deleted file mode 100644 index 66fb5fe9de50c4145a1a097f87a142400ae85858..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17238 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

        oS4SD~RY|St*hd=!XX6PPX~d( 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 K2*z4a0RI9Rx&#iu9ZV(H+P18kdbl&MJLYq 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 diff --git a/env/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl b/env/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl deleted file mode 100644 index 1e63a69c59332682cc4ad0b8a8e7b894315a8795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21951 zcmaI7Q

        wx3!t5M5S$1+O}=mwr$(CZ9B8lw)v)Q+u3!-=lMJpnA_>RQuTK<{ZA_-MFto6zA>T%PYsai^o=k^eW0gkA zPQ3BSYT`2Uvp+dx0`V05GlCb?hmh>z2!Cp_x512Oe1DxKouX?P&t@OSBPtA6PPu;` z;E(g^TwCX<<@wZ-`uW~Svdp(!pUa#$;AgZk*Y)E|ol6Ix_lvTmcSkTHEuu zrO^QQ=hu#vkCfg|Z|Hh{C8Ql4%sO`1MWi9NO^cEnwtN%td-~pkxLzeuE3Oz_EIO=C z+u*AdI%oYCF=r6dEfcIks>mB5IS)QAMWiioDy@&MRYG-b+E&hK-7MVg8kjp~@D0%g zj2l7U=ZyC_ImXW`>72%74M{JorFGFWv{-FSyy4%xol8O|p90UbKkF*B7Gh5;9dqdh z%IY-~Pvmr7Icm0ME;-Iys3T^RmH1s7cr@F_Wwj4~#le}3q1)~}wI+$Msz__5X|2bq zR9UyqZ07*d8{3f!ou*@W(z;KzOI`O(GMl%+}?_!R1JtCVVA7W+cBBbv@tVr ztFD*ytVP_r;iXG0)kt4&VevT`rZ%0AlLVc&BfFc1OSYNnSRRqnrFo*|O}uDe0LQ{0 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 MTwh!0{Qc?w0FgceumAu6 diff --git a/env/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl b/env/share/python-wheels/pip-20.1.1-py2.py3-none-any.whl deleted file mode 100644 index 4fbfb3da154999f6ed10a2ee353a137f38ba43f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 285469 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

        ewxV9jrsG4nDH^_?lfY?P$~kzT|3~tG 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�cqJlFU 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

        DLSmJsc>_&uiTOe-gg~^_J3Nr?4W^@ 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

        _0ToRAGY``> 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 Hu7H05tAt4f diff --git a/env/share/python-wheels/progress-1.5-py2.py3-none-any.whl b/env/share/python-wheels/progress-1.5-py2.py3-none-any.whl deleted file mode 100644 index b795d93ed9a248550e59b5aea5dafd5a102b88ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12812 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 E1FM$f;Q#;t diff --git a/env/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl b/env/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl deleted file mode 100644 index 375b386e2f819afef1ef45723008fb08015a929b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72474 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̞}r+ua)zS`FMD11 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 diff --git a/env/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl b/env/share/python-wheels/resolvelib-0.3.0-py2.py3-none-any.whl deleted file mode 100644 index 7b1a28acf42ef5cb214a5158b5d7331f892e778f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15663 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 D#pD5M diff --git a/env/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl b/env/share/python-wheels/retrying-1.3.3-py2.py3-none-any.whl deleted file mode 100644 index bcd789f8acca8d7cd17827b9c343fdbf38c1d163..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11621 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 Bz48D6 diff --git a/env/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl b/env/share/python-wheels/setuptools-44.0.0-py2.py3-none-any.whl deleted file mode 100644 index e962ad5ec780971814cf1732e7957275b4778c2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472710 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

        K;+jBeox8Wq-`!qyV^rJrwxcKFzxG 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

        7qMTgA?Q)J}&VAT4pFbQQL;;~_~r4O2Z9PX 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%0AFaC~KQ9}Siu(%fxy~wkEKB6YQcW)D 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 aSSkwAVE?7803iO^zyFb?s=5B_>VE+{=r3FV diff --git a/env/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl b/env/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl deleted file mode 100644 index bccd1ad7a2447014f69cfecaeda65562b8188f31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20955 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�~P%xa-97(b8hAcN8si>+W` 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�$v>tX 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 ZZ`qyKA|%><7Z3Qg3LZ2u90p?r@PDw(7$g7y diff --git a/env/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl b/env/share/python-wheels/webencodings-0.5.1-py2.py3-none-any.whl deleted file mode 100644 index c4a86c103ffc06807cb1d3ff5579fc4afeba46cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15749 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 TfqPp`1QX4IJ`|D diff --git a/env/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl b/env/share/python-wheels/wheel-0.34.2-py2.py3-none-any.whl deleted file mode 100644 index e6ac0091e21f4600b201b0929d99054c0f2e55d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30875 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 Y67;WF?2iN*RDd#20D$GcqL%^w55=wCLjV8(

        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≪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%0D^DR3c2J)>d79?LQZ?iewk^+6H{Mfnt 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
        aWIfsh#V;nI8v;f3CNN51*q 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¬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

    Uvicorn is BSD licensed code.
    Designed & built in Brighton, England.

    — 🦄 —

    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 as#O0sV>Ouy9E*Rge9OSbMjZ_$-v2Lf4lmIF diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/comments.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/comments.cpython-38.pyc deleted file mode 100644 index 0e8a77c8e88ad88cd2b7b8c85991c54211bbc314..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1073 zcmYjQ&2AGh5VpPEB%}@Hrz*|O5~n>hE5W6r2qA$up;8gJM4+&Zox~)&-r7!~)%HYr z1`aJ!a^yAo7`}4qD-S z_08}JE-)vfKtCuD4+{JhDk~7^=skG**A&lCpR_^CL;sB`$D_SO8)2ACbEPfwSq&qqItgD}4X*576$V z@5dqEW?yF9g~n=`M?{BS-&myXLS$`!Abk_GS0Cb`N=0l$4~kKlhzHVkwaAr;Cz*`% zqz9?fB-=7V9||3d>@Xh7{Ww3eLzO*jZO2Ahu?2RcWFSl|4fGo?yKLo0F3kNX{Af)L z1fq3Z!;I)#aMylYUPPg*Ej`?t(sCdHG^kU{Y~ZR|r0P&`cXQc5u0>yd))nyW`M68+ z3eP2k@8D8E77I{)!5lY{2gqy|xQzzrgcj&IdcScJ7GXh0Rm}=I#YH&77#*E<0e-uuNHIgl%b$ z)fHyPWQXlWK{*XqN%C9(aP*^+Sya)t!A9Tl;;t9#AUbOR%fUo+{|&6VxRrR$#Tpp8 z6-eK;s_S>pD~u0>suZshiYagn&MMYT(E18WC`uXCT*V&cFnsO*6*}<3584IL=e$(9 puhh8oy_VN+lrEFk9;b>=#^Q-@(`lVJ!}(2c9h3R_^%uq969oVO diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/core.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/core.cpython-38.pyc deleted file mode 100644 index 34b48f9ecfa862388a65499f92d4fb8d3f6722a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7604 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 Jo^rR4{U34sNBaN( diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/exceptions.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index 8d101e407522580a73c43ec1e8064e3619f4c3ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8238 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 diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/format.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/format.cpython-38.pyc deleted file mode 100644 index 51e92cdc2662bdb25f8f87e4931b0b2cbe671b8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5301 zcmbVQO>^7E8OAO?2tt%B$?~_8AZcb2I+o}*Gi|DN5<3>1xZ}{SBqt6W8-=(li4qCW z3($@<)bwBGLi~N>rTbOu^ZAKe2fC+4qz8Cnr4v z&qsgzNBHm4hVf789DiJNuA`(^nPCV+u(lBtH47N}yv;j2;Ecx1w%M@)OSi4I-Ejg( zx9xVR;|6Z09F&={ThY6Cf%laWpSKJ-vF)i%X3$SKLFH>Bo_b)2Qc#iJ{^S8hrLjLH z+yfSz(ycOD({e`62=65q6Qc6M3T8+BNil`~X~9HEoO;P=T)NV^V1SlE=fw0&Tg-^r z7fx^nb93S}c9|1r@YY%Jwq8FY&b>6nd2!)|9i02j5EsRz7lyd>oCoL8yDZ*7?+tnW zxfxs#@5s4gXYnTXc}w_s=b~UMM)emz5RQ#1%Uuy=GHZ1t+Ld11T5m}aiq`r%`qsTD z+pO~3z1z)NNgTCvXH|Zi-M+heYuEYagNKhlc(iNJKYTp@2#Y3Koo=GCu-%Gf?kJh{ zRNTb9j2>!RC^u2kTOfU7-#9S#sAhs4Fm)9z4s`ed*P~pR!lHJ3RhN)GGwH}$Dw{Y$63f~~D+{qSNozo-){UCkrtC!Vd@9vbscJHQT5Gq~YTcb|Gl@T3 z_^6h)GC7ZR+tG$hYpoQZ)YcQ#iL!<6PCipK!xYT5HQHwgk0}s?xy)k~Hbs;xNW3uy zpoxJIfZw14D8>LxA845P0ZShUvu|vd)PmrBNtv{J*W%J_zwBvJwS;YU1b0vgIVbtlP`-N;7FEDlB?c zJNMRGZ5g&=nw!w=!NRicbRoX#61Gs6L7FJ~u|dhO(DAe|{uPbP=v#gBIo|^cf^EC% ztl+Veu|9v!_H?aBuVsASJb)QMZT0!SePC=k2MlXUS*dSqxg@gR0pU^05%xKw?+6F9 zl(FLd=P&`^IeTv3T{0d`?UnoXez_0h!Hg%nT0!0DU(lD8&E#3?NB(iW^nslZ8T7j< zdD;?E`1<^Q6brvNy&r8vtvJobR}msUA+q3kKAw61%9SJdu3TC4Z}_Ao@dnmERHxn!K{orewGZ;q?gGcVrap?z3#_J?6=Y*_+JW$}SWq-7PH^Fz-5x8knjT zxMc0dI$e0ISF-q;Km!E?nLn{QRofd3(*u@>Albg70#qq)1jFV^iB<(?t z05-A%RYsNNZkmO9P?@yQ)4EO;KF!O7iMIAtPrZRz^(K+Gh>UbDFAcv|Xk;99z#s8k zY#YoT7j3;;np^aNlO|&(g)W50S6{`KQu?Mb?ZIkr_U4b4$zeA<=HQ3cq2s#nDp*nF z1!EL3jM-E=|H!6(j*c+MK0?<^YAHhqLDo~4-_#phP5g@9j>! z=Re%3#kD7oKJmeM4Q#1vAh*!@C3SuU@&ozP)vA@-h5fVJ$uoVcJ3vr=+sX!K4xA`X zF>?~occXMWe6}ee-YU$JFd~k^0UtC#xAXLzuLKQwzCC4B%Q4GJCuFcX-9 z2bMS`Z3@za^^yr&I0&LjlI(m5L6s}Y2+qo*z9%No_jJF4`6A?-5GIZ?omW1M(pK}{ zKmqOg^77r~ytH!v=FR%bO5+vNiqkv^81-)wcXakX>$;h-#rj6b1ps=*8gRJ3#!T)M z21sx6ibI2Cd%aM_6BxN6d?v!0aE*4=pJTgcj`OxKTmk1>f=Ngb%lwbqBu#`91#3_k zs0cy{gdkg7@b7d44pz;^E?@LtA+RLbqOeR`2XzCl4!Bkn7%Ec4lNVb`d(9>|k(e9u zJU7PkV8KuD8|nA!Sj_kqZh6R}x{ckdmbya>TqiO@78;~T9ZvFPVF_4JI0ls ze#O-X^zLgFf=uht{Tf>chbbbX^kl_QGy{PrlbYMl6r>tGjgsDR{A$(vShkHahnC9@jS* zE10It+OiSz!83%2_%Ooth^t4+MH_Qou@0>Xy2q;7IKr}8(Q>7h@PXoHk(ulO{S4_< z?&=@`YzEdX1XzK&Twl`f2KHym^?F0=OYYrRTB5F2vOpjM;m*;VoyM?%2h7kd%(= zWI5+b<~H)W=4L*7bQ|Hl8>_4J<%S~1lg}N$n$c8%slqfbQ;QA>D}IaGTB~1&1Zmix zQM4kFKd!(RR}ks!UO0)zn4Uw`J+(qxuM)XWWL%f?3I%(uW(UDQA_~nWmVRETzr<{U zlDZ(s*~*+)*?`9|hnJ8siN4A)PtFY$i@QWna& zqITPFW&R)pl8Et;E$k#cMHxaSJ3gZSXqZufrPPPUDZ(z_q#mJF7&kHwd5J_3|Bn>; zLy7V?>X8`aP6lk_jbp+{<{_WBt^Y`>lUr5fA99PL6^b%DUBnG4#F+XMk#~sD|0Md4 zg4|k5lD3Zbb#SUNf=)~(W^PVTKo}#$n~{>B^ivH8XwTzxn?E)&Kwi diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/hooks.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/hooks.cpython-38.pyc deleted file mode 100644 index d8a1f7bf8d010581e0aa27260929cb204e7b0716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3146 zcmbtX&5ztf7O%41Znt~B5=DsY0xAST+tTz5f@oJ7CDCRRW)}nqG2yEv)bY5gyFFvO zoT~E9bjx!h(sIdx3l~^v=7_|3|A5v00US8_%83L200-c`a`#LpS-9Yq%XWRddhhq% z`@QP-R#!s;*MI)?-{Bi8gnWk|%U2sd{tCDL6dFzjgj4RMbU^LX894BCQ#bPl9>p;) zZDszzx9_dAodts+>kK+sI0z{bzUW>hqRag+9p2`_18=Z0@3SMezr#c5U*#KO&HlP# zov(h`;%j{UL2IzVojuaKH2eIH7$v#TEMnutu!)q1%t#icsXStZ68%_a84MgnDo^q; z%*#0wN=XH;`?54F$qK0qlZp$q6^5mb#$qRAaEar@3}eX!yMe-oDEv>_s3bNw?y6E$ zyHTpeCd(vGM$@IPUidwrMBeVv+IuH56MVjzXw!3R|F+CW$+&i-BB?`h9E-vvGS@w) zZlkK8UhOMkN|nbHh0HGpo-Mdylz#*hPAVT;H+58V@5(F6C?J0pOLJNwjH@NSs{ zFmt)q^hPvO(GdgVi_(O4;!Y8%C}UvUV)hO*6S4R}NL86PQyUSwnV=0v5F1%cj+R&1 z>36|0znN9H;)#e4d#yUu<$j@LEVQm&5DYNA{?2Qv19sIu7l?V!Q5bUwhAva{6;T`T z`Q!Gs$%^eFDf(qzMDd~E{iBHxY5&@_YgzottFLY+8r->!zS3L8v<}C@3>)>=!p&S2c)8>^o-nr9t-g4Zv&j#paeXAH_9ml4gz~L zNsQ27v*=?C7KPw!zKeAv+n+AnWmS8^Hne;XZhZxsG1&I;3I@$7IU}Dr_r1LaVTje1 zl@ES%wqCA1+{0quG?!p;9bQMRAg+p=&!a>X?GuO0o<+2+R$JFo8AE>DgqOu!@F}7W z?l02B*lBY&Th~9nOXpnJ)x{>H9Z>Z&eC^f*;s^o@v$6J@6a;0X*|c8O!Wc~U;V4Ok z3SfF{-3~8!b>YTPvyT22UND2W%RS!W{@6e9Dn~t6d8dTCXOt2{D-Xh;RkidMZ|@P_ zKJkrHxyC*4PFuG1s}^rxC1>=E^5CI!(ym%}$j8M=Pz9%L-Z`V{eb^)9-75Hk{M#A3 zCmj=19grH%UNN16unG-~eL|}?UwP>2uPdLg{)L?Q6;)ru_(~PP$l61Pk`KuJ_dQ}( z57rJt^*>7R_Yw4c2zN!)HrinVWko73WL>~5b07^QWxF>r{_^fmgu^4&KqRn7G7YS{#R{l*wgTIT!nb{a zx^ZyXIZkNM|GAoqgY~gg5thY91_mX7sj&oI81cbG{`CY7xd3J*MkOEy03Ic$jL=VOJ3p+N^zwPAQ4zq`Aj%HE+Z zjJ>YH08uu#;bP8`r;j;05VQL zUaf+~5%ERXPyZPja&?1xG;{)JJ;$RC{GR&B_X6nKpn>B+zk_x2XWzv+mnrtDKCJ9{ zySuvz%Uxv|?V*@CAmWs7`p9pEWbaT7hN(JHSM(15Pc73Ye3rTaAePq5d|U>FpC J_)+JlUjVblczpl> diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/io.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/io.cpython-38.pyc deleted file mode 100644 index e3f2a84e161d8509330ff14ce2004afecf9263f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2678 zcmZuzOLH5?5uTZSVhMmCMaz=Qu598emm!&e;zyO7QWD8Bt?&Z6EXqn&k~d4tfLd~2 znH@+13cQ%Q>Xs^BbRduZ8~GV?^~rz1CwI@13@Lk1^Xlp8?Z?+Wc+lwt1lr9X{uj4= zLVm){`DVlBHuU;644g!SQ_eCPQ8TlM!E9w#Zbvr7Gdpu~H*#|?@^U}&4b90~c@PC= z?Pg1PJ8I{hsFQc2ZoV8X=e?+B&b(|TUyW8N5%lO1_m63`c8~BD4_*=;i0+{ky#@Ov z-iCc!c(A`LE+3NUZO-nKerNu{mtv9@q7IW{7H)2ZQR^=Qf^SbNpt{XP?K~*bvVe=19u)Posz3w5H;Qq|;RE#mbouU4 z_*gxjJh}G%;M(6C`lG-6^$Aj+T>J3RdOS$h=Xchl8|$Axx!xb6`sbSio7>Rq|H2>$ zgoZ@y0TGt4IlV=M12co!h1r7HgO$HaL~FvX5^ld{+~Mv^`;bO~IdeJT-fN5dyk)3M zqRj)o^pXHaM|ix=J7(Pl?q$&fX%0#fE1ZD5F34NvJ-iA0t9%7Qv#RZ{QglhJq)2jY zSKvbJixVgO$h1F!^8%cwec<33gmKKkoYRJDfG4>Nz5W=6c~6lex}e7Z#H-{Xxle4O z*nS{Cq6B}+T7bUa(|?hI{S$x-TCkC%aIY+j7Ff9kwOuhvlxCFgMD+yz?N4s>shHe|Yp(Ehb zH^?niEmwhCyP(fh78g8b!GQ<;%wvte6kCuZi-X?|>7ISe4wxd!L0>6%0kk9Um@F7) zuPpGGHJUq9HCeyeXL1>2$sP=SUv_Yf8cY0&c8&LhMExZe4Cx}-lcFxOXQFS(t4Ksu zjRfP(X1Ickorx^-_|&9#fK;Ot!miNys`0=DhA~F*wBZ_+FlKgPu^@Y7j~+o?I;JM* znhrn%R3Gp+olMdf+RXrnX@$vLi)`|yJ}t<2QPhBeKftZp;E>I`Mw7Fn3tFJMXYkyC zjRHM5J!A)T{;2|O7Gy#9EOhsR9zi-DQ-G+mpx|nY+uV6&A6VR7STXbyFna*z#|@a_ zj(-fG{+^t`*#pb``Mf@KVDbhlev?R6V}1+c7h_3m1YoT>mmM~S z^%J1gD4tktYJ>3sz0APqmN6PRM*U0Lk7KN%ajb(l25(P6ZmipJ{GVx(H763Ed%YaT zNl}z4!9rKZag(qXWQA_mNFC<_Y8IDRLA0}juVRz%?;*jjB*a6infw!MrLhRJL@wcg z4wg4?_`fA)g~@JwfQHoQmH+|=KPY$axQwpZV3!4bnSq6d69aXj;b(3`H#j(b?C`(H zOA=Weix!mkcq6aWY;)^3vBzq$g|{(b&7(j^MoS3ZAAzLpMDEtw-G7erIsHwYa-K`5 z-*@mnszK1G>MVpKHu?+XT2x R*Jzu*%i1ikdLQ?kUjg7^U|IkG diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/literal.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/literal.cpython-38.pyc deleted file mode 100644 index c7bdbd0d29c8d31f7458aa372834e0ce4465e103..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4119 zcma(TO>+~;wR^twVM&&;!8Wikz-F_m0%>bEyV+DZR0xI*32~^kfz4#e)SzzJgJ(vf zdjwb+<$#@HQ>i`Wki)W7_L2OI{ER;2k`w3LxRCdHBv}TwDx>OFcfZ%K-}igBtJN}r z@AH5B%l})IkpJLj`YXWZ7ck^=O2}=(2%{14@ZX4NYu*<3&I>$*dwgKja}253yF7(JA9s( z_yV`N#pgB+KHo8x$$0SNthhn|W1f|s8?4M`_AKuNpY2dQgI^sWmFG6Avf7^QEyBqH zn+41|n*+=xzQm64PJvrf@I|(y;imz< z{0{g@c1pwF1Ndov2JRP++<%Xq(eSeXKg(T!m$=2;BRrgA=QYkbz`5`PIPbF`X`J(n zu9LBdfv zkMSFZs;yqTe&zPf4gc!z)~?_9LOEBvNhjQFBb(EoHQLAzV8Mw;8SxB8Jrk5-Jg3h{ zhcc5{dlk=qMl9kvAgry9-M}Z0NILi|NZe4uvD@y;v>S&5&fK0>2K;GlxSg(W5d|Po zE|CP4IqjS`V~R0cBX1@Qc><=C?2-pGqYr>PW_+t%A9yj>Hb7eYamdmwRcLqPUeHcK znYQfrxKKsk50fzUeKiw>3HKwOY^Gaq!;(Deh*==~f~u15x1&Hx-+w_~`K_&P%v+MT zf%k60TbpoS@LpH8`bpSA`dd5>l1q|{M_jac@~9Ps_glT4bgP?u()_$7L9|PNw;gP9 z+0r@z3~j(>Z%53-qjeNZ%S#8R-d1LF%yy%IA|ye~L4>mJ$6eNsa9#2Jhy5TLK?=Ul zx^3SVkVS}oKvhRFwRsc)U3&oN6%P1&N9-Qp?aMs*-{$`Ek(efvcga+Fiz# z1KQ||qz##9^5H!PhBnd`EJE^El930Hr@%yXmE8Mm2qxR72SlEESZ8KNw+o_~8X4K8 zPZ46Ga~&988$)AgX682}Ggb&-+WVGvJZ3q}7`)mL;4jXjAnJ3O>l0O}N-LW@;ZJ(v@;TUQg<8}ggEQb&6mGz(-Cd$c!Mp@f@M>Z_sB8G*R#E&(yW+><9 zLpad(RWnnMFT$ygBSI}&r$uVOD8j02)M)v&Km|4IoNx(W^U(`bi9bnsBExQ?V@05J zZ8ZD%tH1(_*i{(v6-*grblVX16jZ$n3e9MWM*lc9n8D0_Go}010XaYeSl^r44amOD z>;no;U=8ieLQ@Z|K`kxp7c)2?I(JEO(IRPSyDXkkGAvL6&~iqy!mja@-X)(x0UH+n zT=J`U5ZFwvl%=spS=ICfev5vTqvik|+9dIP3&$ZQ??&{Q$W<$Dx;O@Y< z=qlRGBcw5>okpAm@~V6XBjTD6T_KuqAU?wB5`vsad$lqHsCbo89`reQtSVi5(&jzn zUZ4*t3ndmacolP#numG;1uz9x{Z2n=BPJxG5k1J|jf(bI@e{oADNdNt^Oz`%o)RA; zDVrm2UKL`Lx1s)MLA|Q>^a<(0s7`rvxr%)qRz8|3k1d@*b-SoOnzlNQ%7_?D92K6p}iIYxE)5^m&cFYqw!Nn1R;lVV_@m z=cCvn=tr^j7#krq@nQTOK5pfYqsnsWP07=DvQhE#2Q@ce1OAvBwOmDu!5rt(x`yAW6EZE}78p=Oqjcpwmho zco;uIJ0beEn7EXf*ioRC1&THmABQQixRUqjmod}Ii!d3`UstGWEZB9kUii?g&z?MA PFBj=)C>cvr1NZ*}@E6gE diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/logo.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/logo.cpython-38.pyc deleted file mode 100644 index b5a939bbb2d38760871753794e56b783df21f839..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 537 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 S`p4V1BRyn%IP&gH^bY|8Z*xun diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/output.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/output.cpython-38.pyc deleted file mode 100644 index 545c1ae79f46c73376388f3718fcb2fd52e051d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12013 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 diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/parse.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/parse.cpython-38.pyc deleted file mode 100644 index affff3d329fb7c94cd3e967c654ffe82ac5b7f13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10855 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 Fe*xWb`P2Xa diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/place.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/place.cpython-38.pyc deleted file mode 100644 index 6ceb82d0ceb89769ed1bef43ec04d1aee5964364..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4921 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 COwl#~ diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/profiles.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/profiles.cpython-38.pyc deleted file mode 100644 index 98eede2c6455ad159e783ce7c39cbe7639b0ca57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1275 zcmYjQ%dXr+5cQ15_B=9~`v^CLMKDikkZ!zSlSLE}fmp%@9(Rr1!S1%Y+qoGK z-@#^nAioi1!8i1l)%*bjkf`!Jh%Fy=SDmUlRo#9%pHBmP9{%=Ps51L^0Ua)?ia^AQiBd3Pf4~Zk$e6 zkOH@|-lUyH^Nn!%U*M}tOFN!zt>kg+BEQdaPqBef?l`PyYM9cTP zAIKj2^QNnvWHpvzx^r#k{FPKi-3egMaEXqR6)2DU#af#JSZSnSH-@)e*2j&>G9QfF6TGaeC^|lvGbE%vVFk9IAhS3;sg?DM z8eYgkm)Ke*3ts!Hw;~z5z@gZlIM+sC&DDlsE%0Zh(Opa1mKQ(q5>Vy^>AobmgRuJ@ z0o%O0ug>eX;wx}egjtlbr=JnM?{z@*#K+v}Miz$J-H(GP$Hp`sB;8k5)Ab^|5%yRjGZ_Zib`BI4M8XE#|e3NKspB1wP`=8SBHU zEB*L*O}|+#e8QN}1!Lx%3eX`Lx?ko#!TSU$!3P8%5`0APF~KJUpCb6sI^!3Naiz55 z{b?}vGBBSJgW%1NS*07u@T?3t6qJ?HF$1l(S*K)%gU2h_aCL3LJO`73dY;vCm9-mJ zY4!PohnbZQt`7%fGf895j*UEMH-7x6(W0y2F%93g2=U-791c$Jn|N|q{}U(u>fbm% ac?ZLz|9|U|cg*ouJU#LMK4m+4|NIY@;%2P? diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/pylama_isort.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/pylama_isort.cpython-38.pyc deleted file mode 100644 index 7d673934455e28d59467d273cfa94b66e98cc60f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1459 zcmZux&2Ah;5bmGZ+1c6k#()(PMM!gG4qhW-azKCrL_raj5jJ3FE~D{u@9x+=KXmuv z?8-UW5~nCH-~)&gFTexv7=7iGS3pQmHM0>3qFY^EU0qYZU(dH28zF)5+mFAe&pbl@ zz{9HpWaK_9V}S@Fs3J+X(}cpADOU1?Q#KWB0@2|B4Q}ROP&k_JtXny1$ZX=F?Hj-uB?1w%dE;~ zQpeo!PphT#9u&EC-dIr(up5J;(FQ_FcWcwYVIFnpH?nf9Hm)z^57k1cnCTI?&^LhmO7tddf8N`%WwX;1&Gw>dviwYn?en>mYI}Eg zx6I$adv~WWwYEFWQe|b9wuecxbYrtZG z^C1vPu!#wiTtc$fOfbQ(yrc(bU-o5y`;^@#w~6qsx#$TWZU>?dDF+%Y#msq4X6Me= z(k^tBV?AFEfHwt`cxK`jEZSw=Y@&TQe@`!LW$@^MhZJA zCMyp4Lhk}u33Fc9IXX2`P4!z~xUFJG-hiX)WlGiOZ==gL7PcC7h?uk&F>k+eUMX#+ zw?OT+kTG1W;+OdS9Ec^C-8P(HBYF+C{ z0NxE2Eo&NGH@e8IoIH$aG8To=a+Yb48o<3q(68=1s`6TEnOn7t5K2-+McDvjCQ0wn z;a3OW#Gdn1wJ06WYvnwAV?dXU+>gB$MH-(-66SN6pQRX`?t=hoc@ws-4Y!a(M8DDt zt{2rE5E;BAETD{zIRgswFYoW00RWY)!gYT@c|Q(akfv2u$~1LhnwGU#DC9?J`u!qP z>l<#YcHT){D~+Aj*f!lmg8wW14w8RkX*mQ(3t0@=pjtpTy$-~idW^S2ATC`0WK?mY z5kSs|LKM}k^U<0|N6D~zkP`%HYb6Ok%Z%)DNjAH8Dxc)Cu|-{(wqTC5h3rcDKk>QX Zqb}i3uyY3AZ$JY&qFZc)6KWR*{{T!uO=AE6 diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/sections.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/sections.cpython-38.pyc deleted file mode 100644 index f4ecc113e68f4b6d05c1f8a319589040c6259488..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 501 zcmYk3y>8nu5XY%6N|xhx&ZgA`Vh&w07)9O6Mhyr}AWK8Fu!?!Mh03HrQUTl-=`-Xt z`WRe0f|4#(rMoXuin?e^DiI(HEIGdTZSV4aV4tIkS^7^)C+nAAboL-Xm+cPShi4l1eJHc_zGjo>P2l#n{!i4F1vnsRV>wIcLN}1SG zYOua^4L?fPULZXy##36Fx0KeL3tf**Q7Zi*K1@vFLBc^ID^Ezy1|H<)J2{Cn5c?Jh zT5ur8MpFr$P^9M#>FT{c!MWx)3gjb50{oG*%>(H!`Xu=K#Vt{dh8vsrqdtNn<1B`9 dV;76=Vxr|)u)c*4_Ct|+V+A``?v?Xz{RLB(g6IGM diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/settings.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/settings.cpython-38.pyc deleted file mode 100644 index 6e3cadbe2736c0979383b45065a5957812ffe399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19743 zcmb_^eRLexb>GbF?CfH(SS-LL0D>U3{17Qn;DRDWeNZ$-kN`xABtQWmDUC#}7I*_- zf&Jo}0ZD8Ic5BL(n)-uwT)VBMbdjcR?cU=^y2C@4m0O@9Vzz?)|+xxYW^+(D3h>uYEUvr=n?pK#`6A zx)C{vuR9;nv`d=MY)$CGDCxG&zlLq_Z^Vx9uW6h78?~eSYuOh6#_SmX#_c$MBc--- z!cOSK%Ph5*lXjBB(Nae_Wv9xWc4s+lr^{V-SGn8nE^o27lrwgwyw%=X?y-Byy>>5` zw@Q8GZT2>VVreehTrPMIE81MX&vg)9XAd`sR&onsZES zJFba-`#I-0!rKuZus^XWf5&mnIU#n6N8Z$&=bi1h^ik~=aXPuFR2EO}vPU+h?Z%Tw z#U8O&JSz5y{o*k(C=Q6n#gI5Ca$;B<5>JT3;>cnbxSevkoM*W`PlD4?@sxNPpJ&9b zccS)bC+$3YpL5vmXHo8$J$gSK?SBqw$L%rk347c*C{8$!i|3sK;-r%kBhHXGRgBs% zFt2Ar9;Z=$)IKA|?6YEg!{-HY|8wS@r2V3^1G#5EufL#)7sa_ZHF55ifmWY$&O7IB zVLZfnaiOSx)vzz1#DthciAm%{>Xp0>rSZ_+$Z-7kf)q)}6~z6L&5 z#p_&V8mTi}XI{Jk&X=5tTbg}Y7}MHdp?@o|$IUKQ zZ)CkiCo7!!!b-`@HcMsat1`I zm=_D);$R|(j8s;G_~}BaRG2L}fjL^7^MbZIwe7k@T%p~ zpcxE|S7jO8(BX@vm4#wuwCcDMRd4JjRk`JC<$9r16sU%WgjybKxhSji#genR`I*6JkQhHZH9d22WNPM>z#6|ab7^WUXg@!BdgT20 zgg6YUS0#M{Znw{%=O^}-c#JM?W)H`|Bj=9UlTAun-PpgD%DAv2;-oLK9212~^ zuN#*&UAtz82qe}F^t{}K(gB3b2okPWke+*^h&hT$r&cP=IY>5ghXM;Z3y$|qP3BPi z?i<64)v^OYpOcPPtvJJIa2`)o-Qkr=aky5PgQS-Wm4mJ$uRC(ssazk1EDfunJ(7E7 z*e!a_L6loAEI97)L+d7JJHFsloSQXy;sABY0x@+%OK9>CwKsivqF0r3)yjNv zAxJexdGgZK>9Og0G7QOa*1koO`_j zI$M{4m7iTHmP9>1yE3MISSdMf zkPHQ$_jA|v&pTOoNSDZkv1V*JA=<`9OIzJ!ihp@X9N-ph$7WM}0qO_bg{i8K@ z5?}WNQ_~y`+LUG+(64mpQHE_gQO6PyoZK;-3UQ~+iQ*)&go%`d-QJ2v!xG6>iiNW@ zW_LI#l#V0ZW_RKQvP1&mcDswiNrXG>ZmuH*4qNPuv(<@;PCkz21r6)|;-b(2WQwCZoeMs5i>=fHRuiK9}S+tOQ9=59= zxx1Ej+k2c{=#kQr_HJr9v?Q_9ew2Im2*O!=ABT5wkM?tqpbue$9^>$yumyvy7VHgE z4zyAp4O1R(rR-x4L(E}6hYxc2F%IWAJc#gsJ-n%P2f*o&{RFq@afF*aJ>?WcKWk0AUcG)tQCqX@U#&vN)FE`N;6Kh5Fi zIQ$HUk8_wbxfrxglAL24KEYwq=3@5q96rwBlN|m8hetSkg2Sgc{5-<#tSwsNB&UyZ z`Ur=|IDCr3;~XaKF9wZ}>KzTo`b=xA$2j*a=Zc#^~C`1ypB&!CP=t#xvd^DlG$ zOB}w!;VBNk%;9Mczrx`eggb1Td0#^Kvi+*_nsXKLsPpw3Ly>EEgTqT4E^v66 z!?Oqv+a(Uqg&fK)4g$H3n155VD`G(`;%B`DSaUHQivsGv8iY$-<3Z*!Ue-o24W5=?5a%4+558a`xyE3BbF3xd5fdaA& zOMkIy-IuZsV*z@!rz^ok3W zs&wv5;y4J}OW>R@Ih6%(QIcX7wBLZL*-RO{U&g7>k(r~je2#kI2JMw%hfKVK~gM+QAA?ZJT! zdYqe{EIc&eXiaBmuH@&T(^cha(5_fiG0-yTD#MZ~Vt&whs5iA0kM+Z#lgCh?TWB6e zyKeGGTg8gN+|?u5?4BTnX)7a^uSr-)H!*}fdU-OTg3N{pspy5`!s3Iet??@e(LC>i zlyu6~>rN})UZ~YDK$PL$mBaRfP-`uRB4Pnrs(SQo{V9A3@KCNZz?QS6U&l zaPN;qI9I^~T96xb%@#_9%A6zeH1{>|3_7t6Xg<)-MaOmAnV_R8F%$XO)x5V_a{{XX z{j@lD=N|qATc`nUzAz8@Z1zBQlI--ToLR@a;W(9+xHO+=rV~py=*Gy-(v;lSgMwr; zjdc8=r&vM1plQ;`g7re4CZiA}*d$^p3StQlmi( zO^BdNt;YO~MHm(?Qk|d^>#8|yVD1DdBor%@q=c+9d?pk`7b01}bh%Ci)(J^R%&o3q zFTfJLUX*&qSqvMTeH z>a_y)6*-44c#Eh4D->2F7Kn6%zEFy#BUVrs772`Kv<)V~JfH!uxjQ9cc9N`+^@-Y0 zIho>)oCvmrVVc|dl?rb)Bm^Z?tyXH#<4Fgsn!P7!nS=Ea^s992nh)n?S~fbC2KHgK zG`eT8%Pd3gH>A-h(LRGwh%t0P4ZL2EMFJ!+)Hr4^gP{fCVp(8;-j{0?g&kC!FFGQ~ z7FMty7ise-&adXNtE)L~PCsP+;k1VgYpu!_O z#9>oJmUTHK%r(7oBFv2<_i~tPE$i;ZFdSQs%F7~-k{MO<>zc~>y7sO?b$HR`nEb3~ zi8f#Vx+W4{6ghyLK27zvFGu7rc(F#@*F;iuP>FYq^@vU_Y;%7j%t?6(uiZ;ht8W=g z9k=wbMC!IK&9F?TNK)I3ppt&J0qw>J56W{c*2`)ou-&RUN3wtOPzrF89sg**5 z3eYzZm^2M{2y3`Q26><#z5{q!yF*sdoi-485v0Cl1~8X0^|Rrrnys$^9Bi_jFBKMYS*i=CTd8^jqTZ~|Wlf<~ z)3Iz2fjG;TsELGk$O4gDAT#n+3jPcc+G*vdKAaS`+ zT5-mtM7mX-CFmk(&tpY+SkW?{=O$x`vt5eRAO<{!vSgYbw-j0@-=sdgOymj(Fay(d zO7p7c1l{oYEQb*aI`Vk{HXd38@FxErlH8LZnr`WFy$>|0C+->ajaWv;i0g))x@TH( zJ!4opfiZ@bzGs?oJ=OXcdgfkzYp5yaHu2xI8c9PUG2+!o%hH3i-_obGZ|a108b$F< zUH%%@=(t1@X`_aOcpGP5)@r>7PrRQ4=H+Tb&3# zfXHxZ6L}}{mNt(|L=kG7wiPF$chzXv4)!LbM~EaN6lyd=vYFopjor z4wP0GGo5%QExPz(CI#M|P6WKW@gy$q@MQWe&D88JoLxPErL0#;me|B#Bnu>KSmz~_N=_3x*w5mc!nRjr8gq$+FI0)Hca1K*KvyD zLUo(ghzdaN>juS+Bdq~YP~{>NrH}{6a49~Iye}X|C$4Wc+Jq%y>&BYpB^LCxn6Jz4 zc^!0V!ORpQZjI}tYbWzG$n;&<7>|5@Sy>1a_oulntv`yD4CwxQx zh)Ztq4O|So=Vg3c#(i4nw5^o3W_Uf6_L{NQwid4>iyHB6^rByF+@^#dN6Qk_AG9rj z{B}P94dRo2!s}a(A#_Hx3$3(mE$Js4{UW)pk7`%@);het#&*ABX~6Gj>{!><4PCpf zU(2znw=ej(Wbp@i@mxhxvw=_03i} zlhfP%xNm+nvX&B^ernmeZOFK{%SUV*BxtN7sj0u%{bX^l$mJM*wM21p`%W)0;PvhI=?ekNO{p;X53Vv6g!T5ErZSlJsk9mXZ z`t67`{BE%o8)Mby_keC=+W&5hXFcg1^tas7{ge+lw{j+orF{UvKGoMI zwu^yvBW#;>JK`GPw}biZ^tXcFBdU~_TQ?BPD!$yeVeZ=jj49R7<#(fJ!y9{cT=No* zHuN1czSisa3T-)#F&MpVTpREX`Mr2bwXOTOMrrrk1F4x>>+}1(97Z7`Z{Chv6P4qB zAB~rv=GF?atMP=NZXAX@>1*52>fL@HTDV7*LTInQ4fIjfV&Wh$PyFm3vmB?WUEuzH zxPIaywGF%~mXdkQF@R(52)AmV--flOH=e{i_51yeqmUd^ru_bj>Gv-^wbn28GjCHK z^83YO+cm#`-T(){&6Sf2+S+#JvY*BpecQb@;P?9j+qJbF{tkaT+GNU;{&qUwOggI88c3~tjPqo(|vT4i_^pfz**E;xS9dm1Sy z!`25RO>qAqYZM-$u?WKlRhXO&-b5}rF0AeJcixW5A%7=YpI#%Gu>42DwtfUTjJiXZ zfkQkeJJ-q9c|z?wej3jm^V6vNFl4R^v3b9XcZDo*@rJ*y`B}DnsOQmZqmZPO05Fb~ zwaa@3WiZ1S`DeXj-gDx~qIN5y<{UhpTHEa%_aW&B?_1mB@AmgVUZV0VKEm5He-F*5 zIQov^@A7v;#-i80g74e@E|huC`-H!X_ndJ56+;+v@G4@|zh*S|;=!jTHdqgIh(J|T zNEi+bSlj@Jx|-%|%WP(?XuQ5}Bs&KiqFUZ?=MRHDdjoi-TXW{v#)aMRhuPT`4>l42 zO}dc`(NZopUj+^T=+lJ_Og0Z}DKeZE8Qsd>Sad4cSDPo=RkE}ge^q#B$SzB^HjEcA z@es;Z=d-W!CE?XvcG_`{WfwiK<{lfyCGFg`0$o8buFU3&)$no_nzB2*sbOJEfe*ub zR2R{AYP(8g0Jsc91eGd00!Ug;DRVl;u%1#kw#_^KdORBj<$K6xwf3%_y{qrPtM3jX zUSamG-ZmIjD)Pta&L@d!=jlRaKl@i?X8}`Y>rsZL>yM%pY*4x|44Q*N$VrZTG}tEt zrd)j@Tb$3XFs=ij`u|~M!k*)l@7$SJ{aJ;xhXGqj_~>C|e)cP)jI9sGAW&H(T#i?Sot@ zfv=BkX#0Z(xGECbJ)4`XjPkJ0$FlP8(G;_GPdYv9FFD8hd+0`yYoS@L(&)c{Qg&B( z0i16kXPXR5vIt3OBNNT-16hEQhOLS~7;V{-rmug=xMof(-5jRo7C2o@jh!ALOJI6z zW(Jqc)3`_M&}0RT(!0uSSvL=>&V9`BT~b4NEDa~aDQ0Ws)IoUCt|($Vl)pu>C^-yaAQ%Y>qVOt#>s1u>m0d}$DnU|tE05}F;D%g(CH)-E~Z zxYZIsX{+dxuR~y|YXzAhUJ>*zNB}LJhv?u6LjEe%MYd)T4=+80>_v2NufkP+hw^_w z>2TY|)rkZo@3?k*m_p*9tb1O6ondnGu(6Y&pG{s?s~*Q_OJ(pyZS?=0_**sh z4YTn$UrjV;Q6U$C+CkD9M9^XRK0T4z>|+AY(n8H8+&kP5?PM6>s)CMiZu2bGK=z1u_?%v$UJZiDG(b*9? zvNaa~2DOS|{C(=@dm!J0D_TC!usATL93?Y2@P`O}h_BmE$79UWEyIKfo&W%lz$c}f z(WGIS0N?QG{>U_wfa(aMvtm>(ZY1>-o`@S60CX0fh#M)r$Dm*2=m`LK35NF)NJ}v1 zl#wRBC}D#37(KBJcv3FG5{BM$&x)t;bRWVy@0qcrJ`kZ6nScb-__gqK3VHqa;#MM( zxCe0X&nzp$E$#--G;;$7Zbb@lJZ&V=a(vJplC}K~Ms~p_t*kYHX6sr#q#_nkiSmf*aQro&NU%vuWV_LhSRWc^* zo#lk|bZFhW_KH?9Ue@Y+$!-_XTgDgDYd{7XNnxSR=oRg#_L4TGy-ZK`girq6=99$n zWzFmG$kGQ&KnN*g@v#X$J!i)6>Yoe@IeUjz&|q4AfFJosAh=$xm9Qz@^a88II~Idm zvcY+{5LI4&CT?ip7do9kJ3W4Oe3E=V2`t6U*W|Q@6d_5 z50z+;6p})dz7di)NIb%j6NE?}QzQukp(K1PGaPeDEcp1a;H$VIE1SfFL?ezbiw9;5 z+QJfC3_YEGVR%7Q*0rSw#Nd!;E&;YtDU=Ii)~LiihyV;DBm5;1iUSCNQ1Hdl42crV z-*yoZxTZmR5~gufSbk)I1OTG2)FEQHSo)+Ax<*RG1&mCBkO%-Hct9kP{|&_3MF+)^ zhie)(b}TR5=pxbJU#t1_I$dgg8!!@TzxHizc{f8lF+U~%tpM&wsSt5O?>^*qQV+Y4 z9wP&IEq3jF4FE-c9Hz4FK0`5FW*NPjN|6~=7vP)>*S6J<02a{Q8pnDz z#d@1Ds#Bx@&vn+Pr+9AM>rS zN!RR6{o2j3pXLlSl%iKR4xX+j;idvNOm*p7j~zV7_uA~OaaVusu0E_TfW8HBxT_zV z7$59Y+Gzv{GD>nCQ%A15VV&VvE|GMxs=)UF@_(W{)Qy!{oQ$|Uc7q6XRv9A(iBJTw z#8|1~tAwBp*D%GK%;it$*(k4FzF`Pr^A%oSbnMf3kmo0#{zVsyYI(3tEjzsbfcpXv zJ63i1919@sF1#~rT!Z6QxKym;ewGh7<;=oMB2G1v7m96?bIU`TF0Cpx&VK~nE~#*u z(T`Iijt`wBCU*GDJ+(dwHl|%3do}iSI&t{K(z}tC#r}N&rR!ZA)~n*YNq;ARmDVGT zx%)oI+gND;jM`+HLetRa-v;RF=?gl&m+~g%14_B2_u?|wi_ltxy#6BAquGc;UI9=x zEPyo;F9v`i!qA!N#oq?FiYMDpCPFagt;kxGQiZ9?hzL>uy86~Fz0pqVYc0lrHDKH~ z<9>|6khmX5T~Dn6r1jgdp##1~ZAk%WbR8>0w4+T4YIQ?x;E8qJH|7Db!vDH)?Mc<2 z!Q{lI0r=?#OynU0M()5Mg$9f4ASu|q&C36X{2kz`%oNG< zr3J^}iu`p{ut86vPVJ>mk*x4}pcx~)?UHNQ0w%6BOeDX4o0&3unq^?dEwdVu!T*vl$1>J zn-wWg*&-4B3 z)P7bW$B@@cL$e!68kU}gh1!EfNs3nwj!;qqjgPEoTp!T;jr!J)mxV!H?gyt$Q;s+r z*L+wWLIlS{xHu_bO{8Cy4M(1t>ju z*}~Y9o#4KP!fwYx-w`zcExm%@4|tLWz~tr{TKz!S#iqf~^my4I@XePE22HktB`M*` zBC*(@a5qR`tEwRVAjjdROsawJ*XzB1PTlCmag3)LWIWaSN8=I0m&fHK0<@l#TM5+6 zr{2=u(&r7{`{JJ7Fe#@IeOq6$-iAg(tB$mh3Szi0!s^4=Me1kAaJm3L3}uzh*U*;+ z&NbvUS;)2=l^82i#}p1-LLG6E;YszT#wK~7W|IQNTfhMXcnjE#jhJ<8rV%s^TP-#O zCcioXf80K^ zVai*8%wSCRQN14!YgV3NP1k}L6~M4;XjDWUwlr~gF)74-Rcp=?2VQ{35PF)LlmtHw z_E*x#d=$4VqrUy8Gz=TyAk|M~Vz66&mm>d^2pKI(yGT%Ik_g#}67N5TH{qm|%V$-q zBouadgi6{6l&8T96ry>O)HHJYV8e6H!44A|pDfa8D#u;;J_^&e$oqOc!gkDu21eJ= ztq;?m(k`d^(?c*jdkwuWCaE+uZP?>{qpD2*hc*uq7CJ9ZH~D&yY8Ya8cY>}|7@>@ypWx8|-is>1-Y3-VLL^(1XS|V2d`JwMgl!?S0BQ=Xo(^`Z^>nFj<7kjOdY+4?+<@K+X1H25fAVMAQ|@N{Qc=8 z?Q=kvHa#B+B7_x=QfN5@lN}9554b!4KB?>jXc7n9Qc<9Z*Cq_#Bt4%l zzHxaNRRD}1m3`odcQp)bXRwO+40WRra%-nw4B zHnA*Qpo1N9FAd@mBCSJ79YasjRNSEqvc-b7v72*_x}-=^;(j80lJcsF^KoW(g{E=% ziX6O=?I=KOfV@rEmrhyUx9zR9D!*OLF_1kphIKH#320FK~E!>#<_ z+IPUWn+#p~omMVloco>oD5X!H5L3C@qG`!G=sGth@K49)eHZLeSVTT7}9``3zhrR zR=K-kTeBQjrCQo?1V&E2ee83k5_KG3+g+%(J z4dB+L>=;s}RT#cKyMZ0Y);hgD@)TH0`)O|*ahG5Awt4;JLquHs7+U>ftTVMuEFYDoz%Elfa zKwVfP+Q&718US7v{37ylJqeEs;?jkU@(?!4y~_!t<5;1O@@S&j61%wkDY3g^h&^jv z;g;DIay$f%d$~j%z7gOD@b6K0MrFi4f;70+uqG9Q7mwf*bN>Y1nWh)8)nza31M(8K zu)F%JT94qJ_GnmrM3F*2k#^|oP=Rvd6_oY_fR@Ws+X1U_R(s|VNEn>Zzcgu zlfR2Xb{l*W@Vbh??Ich;*!}W{NWMerlDgUoDAWlO-~#KWdQ(ch+a%9XDm;eg*>`wT zzeyV*Wtsa;hkg+~zq%Jv$44e^9`towXS=%zj`nCzqT|x|xedyMsT5|D`a`xELmVN@ zBHJnTeM)5o;=UGnf z`FBMAJ;>mGxr3U(y3H0!{a-}r&{8V?A0SHe3a5SiDHsHC`@Kx>uh5ai_>r`e%AC4L zXp*$s=!$~fPE>dA5ku;I5W&r%{4+%DcDRQ(fg1UrsQ@X?e6K724?=kVo8GQrjbA|k zq&%uC+wW1yE5wg=P4@X_)QI$+4af9LEzQPH}W)9zd&S>$TE@lQHQ;S@6hS}A4V|v zbu;-iWpAEyRwq75lYJYHX@<$bEv^jdP{t<>3<=kR{H2RQ*nM1r-Vq>7iLV;93?SbO zN)A9+2>K-t;sigtlT*{cn)>Lf&#*qStZwk53&sR^5I2h9ViAQ;5`4bmG&B*oIrQX+Tt-0fq2Ts1V|I&)1Yf_-S43Y;^GeSmdo2@RC<0 zTgcKjL@$q!M+9yj3SJg}%L4E@Fud?a0yhxj^rr!akVBV9{Gw_06deB@xMATvkRl#N zarH{+8K-c)h?i4g&eZS%7+!=W<&OU5!-`id!RgDBUX>(B6|ZNC>aV0^@n;F(u%y~C z0h1_`pPre@pPHOJKQ=Pa{38e~SV8=pv&vU=ENp=5-p5cpIJGVY>vw5tY46lbyug8v zq}0JH@}JQIH4=y;L|D^&fz9fIl3UnOJr!WE5VPiLcB$KA(gf&{CSX7 zdfid^@6*Pm-c=wROH$PeexS`n62dRZI$>}kh|`~(!K1EBQQ9DpG>9Dw--4B0lthZ2 z-G+B`D+2ChLeicQB=B~o(tcg`f?#(McIaSN2lfn6knc9)@!LfDiEJlAmMo*^{2GLv zXyFMizhfb@lz)*1;1rQZi2Mqr{R<-hlE`i%w8G^-C&F6$Z&8T#@DC9RB7`74L1{;b z5JJGJJA1uI=zk&hJVF_NO5{HfxlS1j_53G_{)ou;i4YjUCN0}rtRgFWfcGbwSv%Eq z#!-LaV}nfG-{<4U6}Ef=4`?p+$ij;}n?H0ze+as|f{y#}q5>^Zy0yo`#`4VI4xfAl ztb2WtOiaN;tk;un|8bu`G47=S8HJyp?2Ki|CV)YPl+E9tWa7A4inPi$pHaU*w$gDO cFjTBN0{SWKe19wx>ra^a?yRY2?R4V*0s*9yL*fMix+Wp-d^PT*jrXQpn}3R?Od zr|qCk3ANHr<^>+i5o)L1tQYh!x{Iho-4}?utUWrhZw3n#KSKT1Yd9CJ_lY!bLZSy56nZcW!Lle;nR?uzu&>-B=l#e@qx$ zhgNNZU`V+W7#rYXU{WI>LljudX3jEVE;X;I%UZu-YE$P030kv}OIt8%vkvo?kzQ}p z4$O3C>mKdGs7DF7(v#l3M+Fx*i!6(BS{IMEn13}+qpG_4Y<}gLuP6Pa^2ZgU{^p)v zF)=PhQKXeG3cqB0Q1Gnn!;@qs*sT0`i^bcOU*tY#LjZ+w*qIe{oU&?FYt}0d$2k}U zb)`02n^#Zrxr3w!hx4!~MN;I|Isj^OxCPH+1@qCP;=_V=6I!(jLLh3gNkOnnIWA2+6?JQ9Qpy2hsCCT%MSG)zgC5el2Pg;p!StT8CI}(Be z`=ny&0Ahj-qH!uhSP)4*tfaZkK>c}?j@ciGFM)}FzgQDlxmG6S$~Z5hc$?9c-7Ut_ zl`B`SWbviTm)A4~Yi}?O<0&Q8DxAHTn$Ak>6n% ziLLd%DO(XAjx&~vN*YBa?I9EKF70D}5>C>1OoehmE)0_Vm}Bq5Y^5kfhK=hFj=A-= z?lGqn<*LQds$W1TM@EhZSCKW}hjETf5;pQjKaF!Qj% z6fYxTj>yP5gBtS;tTyI>O^xZ?q45oZkU6g{I{c?;50-lqLd}MpMtc1@C90&vNHJc!IuhV*z3)nIeuH$6cF4}`Eu;zOibhEk z2hyxqDILzrG>VyQmwVwXvHF(gAn@ikLP*a>fm3b|l`ZKiZu2N(Z?m;Hf0Iy0zy$@j zA`O`?grbKDc5xfp5?(U&jPX`*zH8$ck1D7=XgWB5g%^eF1lRz^&;i!Tn?m9m2avoY z>%eZHHXa&>7_fghA@ynDjNFC{fXA1(`ihzp;|bciNRVi4w|R}x#KNdPE1>K*7*1^%Q*zd!9nuS!@jcQgjYHY9E4*E)mZ9otj((dLGxOHu7jQ zWx57J$zVD!{Mz;DSWj{XTvl5_arp`fiRr^Z)0 z4<6m-yx?5n0@UtRlCU2V(YL4hr0fQZyS&JUp{k>dPI=KrgHE|8wu*de%3|7(sz`Gg zX!3D>38t#kAP}~JKo6hA2JQig3-}_8>xE-!2pjq*q#K4RM8Z(E!&!jAyBCH#<0zf2 zIAKVO7^XXvRWVO=8Q~pu0hOxU03lC=VU*_ulvP#L!;q_sa1~Nq)dBEXaE%;S#e6O# zwIiyEaP`B`g;w=Iv@szBFBmgzpRfg(%KmABJvrni#?*Hy6-D}e<{8CllY5{}`0J{LSXSfDr Gj`<&WL{otP diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/sorting.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/sorting.cpython-38.pyc deleted file mode 100644 index 931757973a3df492243a62af48cfc20aa3091898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2958 zcmZuzO>7&-6`q;>;gVcZw5<5AZp@--p|xYu=#OEzu3}rM&;o@D)Cf?pu80+9L~XR( z-Oh|0i&&nlqP-MIPd!8pM4%Vndd#UPa_*t$K@SCb$}PvlK+wK7OIfnprS{FdnfKnj z+4sHo^j@pgAn@GzSsOjYDtH<`+Sx zB|H(r4oc!L?XE8z5ss-~J75c>tqyM=IedwCK(Ygt7(aK!_%c6# z=nl>S@8P+2ZH2!9Ys;KIBGKi~;D%%~@{IE!J21g|oTl-1DopSbEu@{fKTVW2!Osev z#$V5~on$;cx3&7t-5r@v%4AaHQb*ls(5L* zGEKF=J*UgpDtS-j~_PN4FPG6Gj)_b$HeH zz&%ZlDW@fwvzcG|^6iqo&*T-(GRB=*t*jk8rGMgV?T?0yB4EB7YuGc-?fD?}7WZKF+uZ+%lmWbrkI0`KKtgkK+S*!u z+`ADyR@Ya1*P|D-Yv|ArLmwFW(9m^RgAXh*{4eO;XxT6+j5mq(XxDV4cp{_{Ln+c& zCr^ZN-_MiG_+y#x7s@ygN8_dW2SS=wF1e7y?Sr8{D1@m4B$SRbtxRo{#!3lg>Q7>s zAoyS{QTs&!YECLL(?*O8mB>_LPiey9Snm!M0MD$PVTLEbd2O`<3z*9DRR}{&ys!-kMypX#MwG+=-oW~ZtqSXZYXYo z++I8us-NHu`$&>(+$#=DW06*S;sD)NcY%-~q%LjKHgj=g0c+3(^;?&+-UdFAC4K0Ro;iO!G zw#8?iKOv@aQ2k_nBHgCSNH%WLUV+%J3$*-f$Zvu(xvWN4R zP>_9O5%xCx@)pcYZBeW%hYC_SO`+*+K4-?&;;F72z{+>> z;2aOf2q~-<8eBk-JcF+KoNhvcY(WdNMu%_(^_(ht@X~z%7-8vdGbEmyNbj^g4)KfZV@^12e@XBT*sM>5h_+Os=qwr zJy=r#5W)iLJC_{!Bb53fkkRWG$0N|1Li}ScL!;|xXt;R!k~|{v9oUE%7H^(FT>DixqZ&H-Gx`ViYZn|vPonBj@R#*&89I91$HqMb!ziB=YddHRt@?zK={H`9 z@M)Az<)_~2V}2uwSe3Wm2hIQY8Egy%+FpEw`!J8(jg8F>q#GL%AnLreVSMPC&;x9o zB|=c5KUM7UzakSTp|MLSiQ$B%3XUhKkeGw=4iW^5akuk4wRPX-TorEo_!Xc|lle4Q y!M&>KtRW!OyFdbZm4(=4d_wK-1*0cFAG!?tGQ73e`LbGvwUgf$;kD~w$Neuv+SlO# diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index dacedee242f2991123d1241de255aed460c9dc72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmZ8gPiqu06raq@ZpXz+6})%~#e)m&&cRC$B7zk>)IX@DP?RM*Nq5p_k|8hCbz%4B zcM!otd-QAgF>>|fSMcOZW|3kb?@f}I_xt@`-W+dlj}jaQUw=-&rAhKDEN+er7te6Q zLo__$L?x%aC#OWDBID`zlxIBulAq?Byidl1-x!&^9;ZHUnXCQK3fEa(k+8iPIr=c4 zSMZ2*V!s_$<@{>y(SmK zHCYApj2$7+y9fzXo>5l|I+vG1)4+y`&k`I^ra5H_3~iXJY5_5%hV|b^;q+RZgBisMaU%fdzK6=rg&kQQ-%S=Dm?xu*ni12plY7`bI z8?BZblC*=MDO9MJ-dD>CrlQbEyz8@t)PBgBML#ZlYQSQrB!1Xa^%*R|7p-Cr6*qna zj#&o_iElrER!Qf#6c(LJJI*&Zt$T)L?ht%0)BvTRv}yc?$XLD)-SOQA1IC1+(Dr9Pes&1F}Qz5PJ{z#sfPj8X9{(!F8s ThM3|>|9($H*F$Laf)v?bCl3P} diff --git a/env/lib/python3.8/site-packages/isort/__pycache__/wrap.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/__pycache__/wrap.cpython-38.pyc deleted file mode 100644 index 6a6d8a5bd8ba6fbba0cfdb4b0e6e431505164ed4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3194 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 diff --git a/env/lib/python3.8/site-packages/isort/_future/__init__.py b/env/lib/python3.8/site-packages/isort/_future/__init__.py deleted file mode 100644 index 4d9ef4b7..00000000 --- a/env/lib/python3.8/site-packages/isort/_future/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys - -if sys.version_info.major <= 3 and sys.version_info.minor <= 6: - from . import _dataclasses as dataclasses # type: ignore - -else: - import dataclasses # type: ignore - -dataclass = dataclasses.dataclass # type: ignore -field = dataclasses.field # type: ignore - -__all__ = ["dataclasses", "dataclass", "field"] diff --git a/env/lib/python3.8/site-packages/isort/_future/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_future/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 9eb5649f3b6cbd17bb8f838e0afff89b6bf28131..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 411 zcmYk1u};G<5Qgofaokd1L$b6?6b z_i`dDJ?X24U}WfdnluDRS2uMcZKx!&mULG(Q;FZuVtPuh=;f5RoJdBx0WENxb18z@ zXyHBhcy%eJ{~}gf1zIjPb9=D^&y=?=Fuonb=z#HbUGn3r;TY*dZ{?`rF@M_66KHXVZ%SGaOo~4orElf{ diff --git a/env/lib/python3.8/site-packages/isort/_future/__pycache__/_dataclasses.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_future/__pycache__/_dataclasses.cpython-38.pyc deleted file mode 100644 index e4521667023851c7cf2dd0c21460649e8d4bd718..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21748 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 jIosSX7}Evb~-m?l`{N*7frJ+$aAJ?~~v% diff --git a/env/lib/python3.8/site-packages/isort/_future/_dataclasses.py b/env/lib/python3.8/site-packages/isort/_future/_dataclasses.py deleted file mode 100644 index 87acb666..00000000 --- a/env/lib/python3.8/site-packages/isort/_future/_dataclasses.py +++ /dev/null @@ -1,1209 +0,0 @@ -# type: ignore -# flake8: noqa -# flake8: noqa -"""Backport of Python3.7 dataclasses Library - -Taken directly from here: https://github.com/ericvsmith/dataclasses -Licensed under the Apache License: https://github.com/ericvsmith/dataclasses/blob/master/LICENSE.txt - -Needed due to isorts strict no non-optional requirements stance. - -TODO: Remove once isort only supports 3.7+ -""" -import copy -import inspect -import keyword -import re -import sys -import types - -__all__ = [ - "dataclass", - "field", - "Field", - "FrozenInstanceError", - "InitVar", - "MISSING", - # Helper functions. - "fields", - "asdict", - "astuple", - "make_dataclass", - "replace", - "is_dataclass", -] - -# Conditions for adding methods. The boxes indicate what action the -# dataclass decorator takes. For all of these tables, when I talk -# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm -# referring to the arguments to the @dataclass decorator. When -# checking if a dunder method already exists, I mean check for an -# entry in the class's __dict__. I never check to see if an attribute -# is defined in a base class. - -# Key: -# +=========+=========================================+ -# + Value | Meaning | -# +=========+=========================================+ -# | | No action: no method is added. | -# +---------+-----------------------------------------+ -# | add | Generated method is added. | -# +---------+-----------------------------------------+ -# | raise | TypeError is raised. | -# +---------+-----------------------------------------+ -# | None | Attribute is set to None. | -# +=========+=========================================+ - -# __init__ -# -# +--- init= parameter -# | -# v | | | -# | no | yes | <--- class has __init__ in __dict__? -# +=======+=======+=======+ -# | False | | | -# +-------+-------+-------+ -# | True | add | | <- the default -# +=======+=======+=======+ - -# __repr__ -# -# +--- repr= parameter -# | -# v | | | -# | no | yes | <--- class has __repr__ in __dict__? -# +=======+=======+=======+ -# | False | | | -# +-------+-------+-------+ -# | True | add | | <- the default -# +=======+=======+=======+ - - -# __setattr__ -# __delattr__ -# -# +--- frozen= parameter -# | -# v | | | -# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__? -# +=======+=======+=======+ -# | False | | | <- the default -# +-------+-------+-------+ -# | True | add | raise | -# +=======+=======+=======+ -# Raise because not adding these methods would break the "frozen-ness" -# of the class. - -# __eq__ -# -# +--- eq= parameter -# | -# v | | | -# | no | yes | <--- class has __eq__ in __dict__? -# +=======+=======+=======+ -# | False | | | -# +-------+-------+-------+ -# | True | add | | <- the default -# +=======+=======+=======+ - -# __lt__ -# __le__ -# __gt__ -# __ge__ -# -# +--- order= parameter -# | -# v | | | -# | no | yes | <--- class has any comparison method in __dict__? -# +=======+=======+=======+ -# | False | | | <- the default -# +-------+-------+-------+ -# | True | add | raise | -# +=======+=======+=======+ -# Raise because to allow this case would interfere with using -# functools.total_ordering. - -# __hash__ - -# +------------------- unsafe_hash= parameter -# | +----------- eq= parameter -# | | +--- frozen= parameter -# | | | -# v v v | | | -# | no | yes | <--- class has explicitly defined __hash__ -# +=======+=======+=======+========+========+ -# | False | False | False | | | No __eq__, use the base class __hash__ -# +-------+-------+-------+--------+--------+ -# | False | False | True | | | No __eq__, use the base class __hash__ -# +-------+-------+-------+--------+--------+ -# | False | True | False | None | | <-- the default, not hashable -# +-------+-------+-------+--------+--------+ -# | False | True | True | add | | Frozen, so hashable, allows override -# +-------+-------+-------+--------+--------+ -# | True | False | False | add | raise | Has no __eq__, but hashable -# +-------+-------+-------+--------+--------+ -# | True | False | True | add | raise | Has no __eq__, but hashable -# +-------+-------+-------+--------+--------+ -# | True | True | False | add | raise | Not frozen, but hashable -# +-------+-------+-------+--------+--------+ -# | True | True | True | add | raise | Frozen, so hashable -# +=======+=======+=======+========+========+ -# For boxes that are blank, __hash__ is untouched and therefore -# inherited from the base class. If the base is object, then -# id-based hashing is used. -# -# Note that a class may already have __hash__=None if it specified an -# __eq__ method in the class body (not one that was created by -# @dataclass). -# -# See _hash_action (below) for a coded version of this table. - - -# Raised when an attempt is made to modify a frozen class. -class FrozenInstanceError(AttributeError): - pass - - -# A sentinel object for default values to signal that a default -# factory will be used. This is given a nice repr() which will appear -# in the function signature of dataclasses' constructors. -class _HAS_DEFAULT_FACTORY_CLASS: - def __repr__(self): - return "" - - -_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS() - -# A sentinel object to detect if a parameter is supplied or not. Use -# a class to give it a better repr. -class _MISSING_TYPE: - pass - - -MISSING = _MISSING_TYPE() - -# Since most per-field metadata will be unused, create an empty -# read-only proxy that can be shared among all fields. -_EMPTY_METADATA = types.MappingProxyType({}) - -# Markers for the various kinds of fields and pseudo-fields. -class _FIELD_BASE: - def __init__(self, name): - self.name = name - - def __repr__(self): - return self.name - - -_FIELD = _FIELD_BASE("_FIELD") -_FIELD_CLASSVAR = _FIELD_BASE("_FIELD_CLASSVAR") -_FIELD_INITVAR = _FIELD_BASE("_FIELD_INITVAR") - -# The name of an attribute on the class where we store the Field -# objects. Also used to check if a class is a Data Class. -_FIELDS = "__dataclass_fields__" - -# The name of an attribute on the class that stores the parameters to -# @dataclass. -_PARAMS = "__dataclass_params__" - -# The name of the function, that if it exists, is called at the end of -# __init__. -_POST_INIT_NAME = "__post_init__" - -# String regex that string annotations for ClassVar or InitVar must match. -# Allows "identifier.identifier[" or "identifier[". -# https://bugs.python.org/issue33453 for details. -_MODULE_IDENTIFIER_RE = re.compile(r"^(?:\s*(\w+)\s*\.)?\s*(\w+)") - - -class _InitVarMeta(type): - def __getitem__(self, params): - return self - - -class InitVar(metaclass=_InitVarMeta): - pass - - -# Instances of Field are only ever created from within this module, -# and only from the field() function, although Field instances are -# exposed externally as (conceptually) read-only objects. -# -# name and type are filled in after the fact, not in __init__. -# They're not known at the time this class is instantiated, but it's -# convenient if they're available later. -# -# When cls._FIELDS is filled in with a list of Field objects, the name -# and type fields will have been populated. -class Field: - __slots__ = ( - "name", - "type", - "default", - "default_factory", - "repr", - "hash", - "init", - "compare", - "metadata", - "_field_type", # Private: not to be used by user code. - ) - - def __init__(self, default, default_factory, init, repr, hash, compare, metadata): - self.name = None - self.type = None - self.default = default - self.default_factory = default_factory - self.init = init - self.repr = repr - self.hash = hash - self.compare = compare - self.metadata = ( - _EMPTY_METADATA - if metadata is None or len(metadata) == 0 - else types.MappingProxyType(metadata) - ) - self._field_type = None - - def __repr__(self): - return ( - "Field(" - f"name={self.name!r}," - f"type={self.type!r}," - f"default={self.default!r}," - f"default_factory={self.default_factory!r}," - f"init={self.init!r}," - f"repr={self.repr!r}," - f"hash={self.hash!r}," - f"compare={self.compare!r}," - f"metadata={self.metadata!r}," - f"_field_type={self._field_type}" - ")" - ) - - # This is used to support the PEP 487 __set_name__ protocol in the - # case where we're using a field that contains a descriptor as a - # defaul value. For details on __set_name__, see - # https://www.python.org/dev/peps/pep-0487/#implementation-details. - # - # Note that in _process_class, this Field object is overwritten - # with the default value, so the end result is a descriptor that - # had __set_name__ called on it at the right time. - def __set_name__(self, owner, name): - func = getattr(type(self.default), "__set_name__", None) - if func: - # There is a __set_name__ method on the descriptor, call - # it. - func(self.default, owner, name) - - -class _DataclassParams: - __slots__ = ("init", "repr", "eq", "order", "unsafe_hash", "frozen") - - def __init__(self, init, repr, eq, order, unsafe_hash, frozen): - self.init = init - self.repr = repr - self.eq = eq - self.order = order - self.unsafe_hash = unsafe_hash - self.frozen = frozen - - def __repr__(self): - return ( - "_DataclassParams(" - f"init={self.init!r}," - f"repr={self.repr!r}," - f"eq={self.eq!r}," - f"order={self.order!r}," - f"unsafe_hash={self.unsafe_hash!r}," - f"frozen={self.frozen!r}" - ")" - ) - - -# This function is used instead of exposing Field creation directly, -# so that a type checker can be told (via overloads) that this is a -# function whose type depends on its parameters. -def field( - *, - default=MISSING, - default_factory=MISSING, - init=True, - repr=True, - hash=None, - compare=True, - metadata=None, -): - """Return an object to identify dataclass fields. - default is the default value of the field. default_factory is a - 0-argument function called to initialize a field's value. If init - is True, the field will be a parameter to the class's __init__() - function. If repr is True, the field will be included in the - object's repr(). If hash is True, the field will be included in - the object's hash(). If compare is True, the field will be used - in comparison functions. metadata, if specified, must be a - mapping which is stored but not otherwise examined by dataclass. - It is an error to specify both default and default_factory. - """ - - if default is not MISSING and default_factory is not MISSING: - raise ValueError("cannot specify both default and default_factory") - return Field(default, default_factory, init, repr, hash, compare, metadata) - - -def _tuple_str(obj_name, fields): - # Return a string representing each field of obj_name as a tuple - # member. So, if fields is ['x', 'y'] and obj_name is "self", - # return "(self.x,self.y)". - - # Special case for the 0-tuple. - if not fields: - return "()" - # Note the trailing comma, needed if this turns out to be a 1-tuple. - return f'({",".join(f"{obj_name}.{f.name}" for f in fields)},)' - - -def _create_fn(name, args, body, *, globals=None, locals=None, return_type=MISSING): - # Note that we mutate locals when exec() is called. Caller - # beware! The only callers are internal to this module, so no - # worries about external callers. - if locals is None: - locals = {} - return_annotation = "" - if return_type is not MISSING: - locals["_return_type"] = return_type - return_annotation = "->_return_type" - args = ",".join(args) - body = "\n".join(f" {b}" for b in body) - - # Compute the text of the entire function. - txt = f"def {name}({args}){return_annotation}:\n{body}" - - exec(txt, globals, locals) # nosec - return locals[name] - - -def _field_assign(frozen, name, value, self_name): - # If we're a frozen class, then assign to our fields in __init__ - # via object.__setattr__. Otherwise, just use a simple - # assignment. - # - # self_name is what "self" is called in this function: don't - # hard-code "self", since that might be a field name. - if frozen: - return f"object.__setattr__({self_name},{name!r},{value})" - return f"{self_name}.{name}={value}" - - -def _field_init(f, frozen, globals, self_name): - # Return the text of the line in the body of __init__ that will - # initialize this field. - - default_name = f"_dflt_{f.name}" - if f.default_factory is not MISSING: - if f.init: - # This field has a default factory. If a parameter is - # given, use it. If not, call the factory. - globals[default_name] = f.default_factory - value = f"{default_name}() " f"if {f.name} is _HAS_DEFAULT_FACTORY " f"else {f.name}" - else: - # This is a field that's not in the __init__ params, but - # has a default factory function. It needs to be - # initialized here by calling the factory function, - # because there's no other way to initialize it. - - # For a field initialized with a default=defaultvalue, the - # class dict just has the default value - # (cls.fieldname=defaultvalue). But that won't work for a - # default factory, the factory must be called in __init__ - # and we must assign that to self.fieldname. We can't - # fall back to the class dict's value, both because it's - # not set, and because it might be different per-class - # (which, after all, is why we have a factory function!). - - globals[default_name] = f.default_factory - value = f"{default_name}()" - else: - # No default factory. - if f.init: - if f.default is MISSING: - # There's no default, just do an assignment. - value = f.name - elif f.default is not MISSING: - globals[default_name] = f.default - value = f.name - else: - # This field does not need initialization. Signify that - # to the caller by returning None. - return None - - # Only test this now, so that we can create variables for the - # default. However, return None to signify that we're not going - # to actually do the assignment statement for InitVars. - if f._field_type == _FIELD_INITVAR: - return None - - # Now, actually generate the field assignment. - return _field_assign(frozen, f.name, value, self_name) - - -def _init_param(f): - # Return the __init__ parameter string for this field. For - # example, the equivalent of 'x:int=3' (except instead of 'int', - # reference a variable set to int, and instead of '3', reference a - # variable set to 3). - if f.default is MISSING and f.default_factory is MISSING: - # There's no default, and no default_factory, just output the - # variable name and type. - default = "" - elif f.default is not MISSING: - # There's a default, this will be the name that's used to look - # it up. - default = f"=_dflt_{f.name}" - elif f.default_factory is not MISSING: - # There's a factory function. Set a marker. - default = "=_HAS_DEFAULT_FACTORY" - return f"{f.name}:_type_{f.name}{default}" - - -def _init_fn(fields, frozen, has_post_init, self_name): - # fields contains both real fields and InitVar pseudo-fields. - - # Make sure we don't have fields without defaults following fields - # with defaults. This actually would be caught when exec-ing the - # function source code, but catching it here gives a better error - # message, and future-proofs us in case we build up the function - # using ast. - seen_default = False - for f in fields: - # Only consider fields in the __init__ call. - if f.init: - if not (f.default is MISSING and f.default_factory is MISSING): - seen_default = True - elif seen_default: - raise TypeError(f"non-default argument {f.name!r} " "follows default argument") - - globals = {"MISSING": MISSING, "_HAS_DEFAULT_FACTORY": _HAS_DEFAULT_FACTORY} - - body_lines = [] - for f in fields: - line = _field_init(f, frozen, globals, self_name) - # line is None means that this field doesn't require - # initialization (it's a pseudo-field). Just skip it. - if line: - body_lines.append(line) - - # Does this class have a post-init function? - if has_post_init: - params_str = ",".join(f.name for f in fields if f._field_type is _FIELD_INITVAR) - body_lines.append(f"{self_name}.{_POST_INIT_NAME}({params_str})") - - # If no body lines, use 'pass'. - if not body_lines: - body_lines = ["pass"] - - locals = {f"_type_{f.name}": f.type for f in fields} - return _create_fn( - "__init__", - [self_name] + [_init_param(f) for f in fields if f.init], - body_lines, - locals=locals, - globals=globals, - return_type=None, - ) - - -def _repr_fn(fields): - return _create_fn( - "__repr__", - ("self",), - [ - 'return self.__class__.__qualname__ + f"(' - + ", ".join(f"{f.name}={{self.{f.name}!r}}" for f in fields) - + ')"' - ], - ) - - -def _frozen_get_del_attr(cls, fields): - # XXX: globals is modified on the first call to _create_fn, then - # the modified version is used in the second call. Is this okay? - globals = {"cls": cls, "FrozenInstanceError": FrozenInstanceError} - if fields: - fields_str = "(" + ",".join(repr(f.name) for f in fields) + ",)" - else: - # Special case for the zero-length tuple. - fields_str = "()" - return ( - _create_fn( - "__setattr__", - ("self", "name", "value"), - ( - f"if type(self) is cls or name in {fields_str}:", - ' raise FrozenInstanceError(f"cannot assign to field {name!r}")', - f"super(cls, self).__setattr__(name, value)", - ), - globals=globals, - ), - _create_fn( - "__delattr__", - ("self", "name"), - ( - f"if type(self) is cls or name in {fields_str}:", - ' raise FrozenInstanceError(f"cannot delete field {name!r}")', - f"super(cls, self).__delattr__(name)", - ), - globals=globals, - ), - ) - - -def _cmp_fn(name, op, self_tuple, other_tuple): - # Create a comparison function. If the fields in the object are - # named 'x' and 'y', then self_tuple is the string - # '(self.x,self.y)' and other_tuple is the string - # '(other.x,other.y)'. - - return _create_fn( - name, - ("self", "other"), - [ - "if other.__class__ is self.__class__:", - f" return {self_tuple}{op}{other_tuple}", - "return NotImplemented", - ], - ) - - -def _hash_fn(fields): - self_tuple = _tuple_str("self", fields) - return _create_fn("__hash__", ("self",), [f"return hash({self_tuple})"]) - - -def _is_classvar(a_type, typing): - # This test uses a typing internal class, but it's the best way to - # test if this is a ClassVar. - return type(a_type) is typing._ClassVar - - -def _is_initvar(a_type, dataclasses): - # The module we're checking against is the module we're - # currently in (dataclasses.py). - return a_type is dataclasses.InitVar - - -def _is_type(annotation, cls, a_module, a_type, is_type_predicate): - # Given a type annotation string, does it refer to a_type in - # a_module? For example, when checking that annotation denotes a - # ClassVar, then a_module is typing, and a_type is - # typing.ClassVar. - - # It's possible to look up a_module given a_type, but it involves - # looking in sys.modules (again!), and seems like a waste since - # the caller already knows a_module. - - # - annotation is a string type annotation - # - cls is the class that this annotation was found in - # - a_module is the module we want to match - # - a_type is the type in that module we want to match - # - is_type_predicate is a function called with (obj, a_module) - # that determines if obj is of the desired type. - - # Since this test does not do a local namespace lookup (and - # instead only a module (global) lookup), there are some things it - # gets wrong. - - # With string annotations, cv0 will be detected as a ClassVar: - # CV = ClassVar - # @dataclass - # class C0: - # cv0: CV - - # But in this example cv1 will not be detected as a ClassVar: - # @dataclass - # class C1: - # CV = ClassVar - # cv1: CV - - # In C1, the code in this function (_is_type) will look up "CV" in - # the module and not find it, so it will not consider cv1 as a - # ClassVar. This is a fairly obscure corner case, and the best - # way to fix it would be to eval() the string "CV" with the - # correct global and local namespaces. However that would involve - # a eval() penalty for every single field of every dataclass - # that's defined. It was judged not worth it. - - match = _MODULE_IDENTIFIER_RE.match(annotation) - if match: - ns = None - module_name = match.group(1) - if not module_name: - # No module name, assume the class's module did - # "from dataclasses import InitVar". - ns = sys.modules.get(cls.__module__).__dict__ - else: - # Look up module_name in the class's module. - module = sys.modules.get(cls.__module__) - if module and module.__dict__.get(module_name) is a_module: - ns = sys.modules.get(a_type.__module__).__dict__ - if ns and is_type_predicate(ns.get(match.group(2)), a_module): - return True - return False - - -def _get_field(cls, a_name, a_type): - # Return a Field object for this field name and type. ClassVars - # and InitVars are also returned, but marked as such (see - # f._field_type). - - # If the default value isn't derived from Field, then it's only a - # normal default value. Convert it to a Field(). - default = getattr(cls, a_name, MISSING) - if isinstance(default, Field): - f = default - else: - if isinstance(default, types.MemberDescriptorType): - # This is a field in __slots__, so it has no default value. - default = MISSING - f = field(default=default) - - # Only at this point do we know the name and the type. Set them. - f.name = a_name - f.type = a_type - - # Assume it's a normal field until proven otherwise. We're next - # going to decide if it's a ClassVar or InitVar, everything else - # is just a normal field. - f._field_type = _FIELD - - # In addition to checking for actual types here, also check for - # string annotations. get_type_hints() won't always work for us - # (see https://github.com/python/typing/issues/508 for example), - # plus it's expensive and would require an eval for every stirng - # annotation. So, make a best effort to see if this is a ClassVar - # or InitVar using regex's and checking that the thing referenced - # is actually of the correct type. - - # For the complete discussion, see https://bugs.python.org/issue33453 - - # If typing has not been imported, then it's impossible for any - # annotation to be a ClassVar. So, only look for ClassVar if - # typing has been imported by any module (not necessarily cls's - # module). - typing = sys.modules.get("typing") - if typing: - if _is_classvar(a_type, typing) or ( - isinstance(f.type, str) and _is_type(f.type, cls, typing, typing.ClassVar, _is_classvar) - ): - f._field_type = _FIELD_CLASSVAR - - # If the type is InitVar, or if it's a matching string annotation, - # then it's an InitVar. - if f._field_type is _FIELD: - # The module we're checking against is the module we're - # currently in (dataclasses.py). - dataclasses = sys.modules[__name__] - if _is_initvar(a_type, dataclasses) or ( - isinstance(f.type, str) - and _is_type(f.type, cls, dataclasses, dataclasses.InitVar, _is_initvar) - ): - f._field_type = _FIELD_INITVAR - - # Validations for individual fields. This is delayed until now, - # instead of in the Field() constructor, since only here do we - # know the field name, which allows for better error reporting. - - # Special restrictions for ClassVar and InitVar. - if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR): - if f.default_factory is not MISSING: - raise TypeError(f"field {f.name} cannot have a " "default factory") - # Should I check for other field settings? default_factory - # seems the most serious to check for. Maybe add others. For - # example, how about init=False (or really, - # init=)? It makes no sense for - # ClassVar and InitVar to specify init=. - - # For real fields, disallow mutable defaults for known types. - if f._field_type is _FIELD and isinstance(f.default, (list, dict, set)): - raise ValueError( - f"mutable default {type(f.default)} for field " - f"{f.name} is not allowed: use default_factory" - ) - - return f - - -def _set_new_attribute(cls, name, value): - # Never overwrites an existing attribute. Returns True if the - # attribute already exists. - if name in cls.__dict__: - return True - setattr(cls, name, value) - return False - - -# Decide if/how we're going to create a hash function. Key is -# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to -# take. The common case is to do nothing, so instead of providing a -# function that is a no-op, use None to signify that. - - -def _hash_set_none(cls, fields): - return None - - -def _hash_add(cls, fields): - flds = [f for f in fields if (f.compare if f.hash is None else f.hash)] - return _hash_fn(flds) - - -def _hash_exception(cls, fields): - # Raise an exception. - raise TypeError(f"Cannot overwrite attribute __hash__ " f"in class {cls.__name__}") - - -# -# +-------------------------------------- unsafe_hash? -# | +------------------------------- eq? -# | | +------------------------ frozen? -# | | | +---------------- has-explicit-hash? -# | | | | -# | | | | +------- action -# | | | | | -# v v v v v -_hash_action = { - (False, False, False, False): None, - (False, False, False, True): None, - (False, False, True, False): None, - (False, False, True, True): None, - (False, True, False, False): _hash_set_none, - (False, True, False, True): None, - (False, True, True, False): _hash_add, - (False, True, True, True): None, - (True, False, False, False): _hash_add, - (True, False, False, True): _hash_exception, - (True, False, True, False): _hash_add, - (True, False, True, True): _hash_exception, - (True, True, False, False): _hash_add, - (True, True, False, True): _hash_exception, - (True, True, True, False): _hash_add, - (True, True, True, True): _hash_exception, -} -# See https://bugs.python.org/issue32929#msg312829 for an if-statement -# version of this table. - - -def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): - # Now that dicts retain insertion order, there's no reason to use - # an ordered dict. I am leveraging that ordering here, because - # derived class fields overwrite base class fields, but the order - # is defined by the base class, which is found first. - fields = {} - - setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order, unsafe_hash, frozen)) - - # Find our base classes in reverse MRO order, and exclude - # ourselves. In reversed order so that more derived classes - # override earlier field definitions in base classes. As long as - # we're iterating over them, see if any are frozen. - any_frozen_base = False - has_dataclass_bases = False - for b in cls.__mro__[-1:0:-1]: - # Only process classes that have been processed by our - # decorator. That is, they have a _FIELDS attribute. - base_fields = getattr(b, _FIELDS, None) - if base_fields: - has_dataclass_bases = True - for f in base_fields.values(): - fields[f.name] = f - if getattr(b, _PARAMS).frozen: - any_frozen_base = True - - # Annotations that are defined in this class (not in base - # classes). If __annotations__ isn't present, then this class - # adds no new annotations. We use this to compute fields that are - # added by this class. - # - # Fields are found from cls_annotations, which is guaranteed to be - # ordered. Default values are from class attributes, if a field - # has a default. If the default value is a Field(), then it - # contains additional info beyond (and possibly including) the - # actual default value. Pseudo-fields ClassVars and InitVars are - # included, despite the fact that they're not real fields. That's - # dealt with later. - cls_annotations = cls.__dict__.get("__annotations__", {}) - - # Now find fields in our class. While doing so, validate some - # things, and set the default values (as class attributes) where - # we can. - cls_fields = [_get_field(cls, name, type) for name, type in cls_annotations.items()] - for f in cls_fields: - fields[f.name] = f - - # If the class attribute (which is the default value for this - # field) exists and is of type 'Field', replace it with the - # real default. This is so that normal class introspection - # sees a real default value, not a Field. - if isinstance(getattr(cls, f.name, None), Field): - if f.default is MISSING: - # If there's no default, delete the class attribute. - # This happens if we specify field(repr=False), for - # example (that is, we specified a field object, but - # no default value). Also if we're using a default - # factory. The class attribute should not be set at - # all in the post-processed class. - delattr(cls, f.name) - else: - setattr(cls, f.name, f.default) - - # Do we have any Field members that don't also have annotations? - for name, value in cls.__dict__.items(): - if isinstance(value, Field) and not name in cls_annotations: - raise TypeError(f"{name!r} is a field but has no type annotation") - - # Check rules that apply if we are derived from any dataclasses. - if has_dataclass_bases: - # Raise an exception if any of our bases are frozen, but we're not. - if any_frozen_base and not frozen: - raise TypeError("cannot inherit non-frozen dataclass from a " "frozen one") - - # Raise an exception if we're frozen, but none of our bases are. - if not any_frozen_base and frozen: - raise TypeError("cannot inherit frozen dataclass from a " "non-frozen one") - - # Remember all of the fields on our class (including bases). This - # also marks this class as being a dataclass. - setattr(cls, _FIELDS, fields) - - # Was this class defined with an explicit __hash__? Note that if - # __eq__ is defined in this class, then python will automatically - # set __hash__ to None. This is a heuristic, as it's possible - # that such a __hash__ == None was not auto-generated, but it - # close enough. - class_hash = cls.__dict__.get("__hash__", MISSING) - has_explicit_hash = not ( - class_hash is MISSING or (class_hash is None and "__eq__" in cls.__dict__) - ) - - # If we're generating ordering methods, we must be generating the - # eq methods. - if order and not eq: - raise ValueError("eq must be true if order is true") - - if init: - # Does this class have a post-init function? - has_post_init = hasattr(cls, _POST_INIT_NAME) - - # Include InitVars and regular fields (so, not ClassVars). - flds = [f for f in fields.values() if f._field_type in (_FIELD, _FIELD_INITVAR)] - _set_new_attribute( - cls, - "__init__", - _init_fn( - flds, - frozen, - has_post_init, - # The name to use for the "self" - # param in __init__. Use "self" - # if possible. - "__dataclass_self__" if "self" in fields else "self", - ), - ) - - # Get the fields as a list, and include only real fields. This is - # used in all of the following methods. - field_list = [f for f in fields.values() if f._field_type is _FIELD] - - if repr: - flds = [f for f in field_list if f.repr] - _set_new_attribute(cls, "__repr__", _repr_fn(flds)) - - if eq: - # Create _eq__ method. There's no need for a __ne__ method, - # since python will call __eq__ and negate it. - flds = [f for f in field_list if f.compare] - self_tuple = _tuple_str("self", flds) - other_tuple = _tuple_str("other", flds) - _set_new_attribute(cls, "__eq__", _cmp_fn("__eq__", "==", self_tuple, other_tuple)) - - if order: - # Create and set the ordering methods. - flds = [f for f in field_list if f.compare] - self_tuple = _tuple_str("self", flds) - other_tuple = _tuple_str("other", flds) - for name, op in [("__lt__", "<"), ("__le__", "<="), ("__gt__", ">"), ("__ge__", ">=")]: - if _set_new_attribute(cls, name, _cmp_fn(name, op, self_tuple, other_tuple)): - raise TypeError( - f"Cannot overwrite attribute {name} " - f"in class {cls.__name__}. Consider using " - "functools.total_ordering" - ) - - if frozen: - for fn in _frozen_get_del_attr(cls, field_list): - if _set_new_attribute(cls, fn.__name__, fn): - raise TypeError( - f"Cannot overwrite attribute {fn.__name__} " f"in class {cls.__name__}" - ) - - # Decide if/how we're going to create a hash function. - hash_action = _hash_action[bool(unsafe_hash), bool(eq), bool(frozen), has_explicit_hash] - if hash_action: - # No need to call _set_new_attribute here, since by the time - # we're here the overwriting is unconditional. - cls.__hash__ = hash_action(cls, field_list) - - if not getattr(cls, "__doc__"): - # Create a class doc-string. - cls.__doc__ = cls.__name__ + str(inspect.signature(cls)).replace(" -> None", "") - - return cls - - -# _cls should never be specified by keyword, so start it with an -# underscore. The presence of _cls is used to detect if this -# decorator is being called with parameters or not. -def dataclass( - _cls=None, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False -): - """Returns the same class as was passed in, with dunder methods - added based on the fields defined in the class. - Examines PEP 526 __annotations__ to determine fields. - If init is true, an __init__() method is added to the class. If - repr is true, a __repr__() method is added. If order is true, rich - comparison dunder methods are added. If unsafe_hash is true, a - __hash__() method function is added. If frozen is true, fields may - not be assigned to after instance creation. - """ - - def wrap(cls): - return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen) - - # See if we're being called as @dataclass or @dataclass(). - if _cls is None: - # We're called with parens. - return wrap - - # We're called as @dataclass without parens. - return wrap(_cls) - - -def fields(class_or_instance): - """Return a tuple describing the fields of this dataclass. - Accepts a dataclass or an instance of one. Tuple elements are of - type Field. - """ - - # Might it be worth caching this, per class? - try: - fields = getattr(class_or_instance, _FIELDS) - except AttributeError: - raise TypeError("must be called with a dataclass type or instance") - - # Exclude pseudo-fields. Note that fields is sorted by insertion - # order, so the order of the tuple is as the fields were defined. - return tuple(f for f in fields.values() if f._field_type is _FIELD) - - -def _is_dataclass_instance(obj): - """Returns True if obj is an instance of a dataclass.""" - return not isinstance(obj, type) and hasattr(obj, _FIELDS) - - -def is_dataclass(obj): - """Returns True if obj is a dataclass or an instance of a - dataclass.""" - return hasattr(obj, _FIELDS) - - -def asdict(obj, *, dict_factory=dict): - """Return the fields of a dataclass instance as a new dictionary mapping - field names to field values. - Example usage: - @dataclass - class C: - x: int - y: int - c = C(1, 2) - assert asdict(c) == {'x': 1, 'y': 2} - If given, 'dict_factory' will be used instead of built-in dict. - The function applies recursively to field values that are - dataclass instances. This will also look into built-in containers: - tuples, lists, and dicts. - """ - if not _is_dataclass_instance(obj): - raise TypeError("asdict() should be called on dataclass instances") - return _asdict_inner(obj, dict_factory) - - -def _asdict_inner(obj, dict_factory): - if _is_dataclass_instance(obj): - result = [] - for f in fields(obj): - value = _asdict_inner(getattr(obj, f.name), dict_factory) - result.append((f.name, value)) - return dict_factory(result) - elif isinstance(obj, (list, tuple)): - return type(obj)(_asdict_inner(v, dict_factory) for v in obj) - elif isinstance(obj, dict): - return type(obj)( - (_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory)) for k, v in obj.items() - ) - else: - return copy.deepcopy(obj) - - -def astuple(obj, *, tuple_factory=tuple): - """Return the fields of a dataclass instance as a new tuple of field values. - Example usage:: - @dataclass - class C: - x: int - y: int - c = C(1, 2) - assert astuple(c) == (1, 2) - If given, 'tuple_factory' will be used instead of built-in tuple. - The function applies recursively to field values that are - dataclass instances. This will also look into built-in containers: - tuples, lists, and dicts. - """ - - if not _is_dataclass_instance(obj): - raise TypeError("astuple() should be called on dataclass instances") - return _astuple_inner(obj, tuple_factory) - - -def _astuple_inner(obj, tuple_factory): - if _is_dataclass_instance(obj): - result = [] - for f in fields(obj): - value = _astuple_inner(getattr(obj, f.name), tuple_factory) - result.append(value) - return tuple_factory(result) - elif isinstance(obj, (list, tuple)): - return type(obj)(_astuple_inner(v, tuple_factory) for v in obj) - elif isinstance(obj, dict): - return type(obj)( - (_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) - for k, v in obj.items() - ) - else: - return copy.deepcopy(obj) - - -def make_dataclass( - cls_name, - fields, - *, - bases=(), - namespace=None, - init=True, - repr=True, - eq=True, - order=False, - unsafe_hash=False, - frozen=False, -): - """Return a new dynamically created dataclass. - The dataclass name will be 'cls_name'. 'fields' is an iterable - of either (name), (name, type) or (name, type, Field) objects. If type is - omitted, use the string 'typing.Any'. Field objects are created by - the equivalent of calling 'field(name, type [, Field-info])'. - C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,)) - is equivalent to: - @dataclass - class C(Base): - x: 'typing.Any' - y: int - z: int = field(init=False) - For the bases and namespace parameters, see the builtin type() function. - The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to - dataclass(). - """ - - if namespace is None: - namespace = {} - else: - # Copy namespace since we're going to mutate it. - namespace = namespace.copy() - - # While we're looking through the field names, validate that they - # are identifiers, are not keywords, and not duplicates. - seen = set() - anns = {} - for item in fields: - if isinstance(item, str): - name = item - tp = "typing.Any" - elif len(item) == 2: - ( - name, - tp, - ) = item - elif len(item) == 3: - name, tp, spec = item - namespace[name] = spec - else: - raise TypeError(f"Invalid field: {item!r}") - - if not isinstance(name, str) or not name.isidentifier(): - raise TypeError(f"Field names must be valid identifers: {name!r}") - if keyword.iskeyword(name): - raise TypeError(f"Field names must not be keywords: {name!r}") - if name in seen: - raise TypeError(f"Field name duplicated: {name!r}") - - seen.add(name) - anns[name] = tp - - namespace["__annotations__"] = anns - # We use `types.new_class()` instead of simply `type()` to allow dynamic creation - # of generic dataclassses. - cls = types.new_class(cls_name, bases, {}, lambda ns: ns.update(namespace)) - return dataclass( - cls, init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen - ) - - -def replace(obj, **changes): - """Return a new object replacing specified fields with new values. - This is especially useful for frozen classes. Example usage: - @dataclass(frozen=True) - class C: - x: int - y: int - c = C(1, 2) - c1 = replace(c, x=3) - assert c1.x == 3 and c1.y == 2 - """ - - # We're going to mutate 'changes', but that's okay because it's a - # new dict, even if called with 'replace(obj, **my_changes)'. - - if not _is_dataclass_instance(obj): - raise TypeError("replace() should be called on dataclass instances") - - # It's an error to have init=False fields in 'changes'. - # If a field is not in 'changes', read its value from the provided obj. - - for f in getattr(obj, _FIELDS).values(): - if not f.init: - # Error if this field is specified in changes. - if f.name in changes: - raise ValueError( - f"field {f.name} is declared with " - "init=False, it cannot be specified with " - "replace()" - ) - continue - - if f.name not in changes: - changes[f.name] = getattr(obj, f.name) - - # Create the new object, which calls __init__() and - # __post_init__() (if defined), using all of the init fields we've - # added and/or left in 'changes'. If there are values supplied in - # changes that aren't fields, this will correctly raise a - # TypeError. - return obj.__class__(**changes) diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/LICENSE b/env/lib/python3.8/site-packages/isort/_vendored/toml/LICENSE deleted file mode 100644 index 5010e307..00000000 --- a/env/lib/python3.8/site-packages/isort/_vendored/toml/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -The MIT License - -Copyright 2013-2019 William Pearson -Copyright 2015-2016 Julien Enselme -Copyright 2016 Google Inc. -Copyright 2017 Samuel Vasko -Copyright 2017 Nate Prewitt -Copyright 2017 Jack Evans -Copyright 2019 Filippo Broggini - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/__init__.py b/env/lib/python3.8/site-packages/isort/_vendored/toml/__init__.py deleted file mode 100644 index 8cefeffa..00000000 --- a/env/lib/python3.8/site-packages/isort/_vendored/toml/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Python module which parses and emits TOML. - -Released under the MIT license. -""" -from . import decoder, encoder - -__version__ = "0.10.1" -_spec_ = "0.5.0" - -load = decoder.load -loads = decoder.loads -TomlDecoder = decoder.TomlDecoder -TomlDecodeError = decoder.TomlDecodeError -TomlPreserveCommentDecoder = decoder.TomlPreserveCommentDecoder - -dump = encoder.dump -dumps = encoder.dumps -TomlEncoder = encoder.TomlEncoder -TomlArraySeparatorEncoder = encoder.TomlArraySeparatorEncoder -TomlPreserveInlineDictEncoder = encoder.TomlPreserveInlineDictEncoder -TomlNumpyEncoder = encoder.TomlNumpyEncoder -TomlPreserveCommentEncoder = encoder.TomlPreserveCommentEncoder -TomlPathlibEncoder = encoder.TomlPathlibEncoder diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 8d4290647419d40b97a5e703a560c5b14e687672..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 718 zcmZvZ&2G~`5XWuDaZ;yg(r^L^$=4j}4MLTAKnO&8sMMBkI%zl?9n>={)_(%Jnwh=c)G~uy`#@6g7Cl- zz6eUc3LvOD(D6Odfl!3d#o!@=h}eT3u@8OX0UQuxh_Ul9fC2Fk4v9k;5|7}BID!#z z3}fOk91|xn5#2j)8m+HxSFX@1skB&>n0zZ_ULJo6J96U!`&U2}{f@ zie#Y#n#2{DTwl(UQs$^Ertu%2N|**sPhhSoqUoX9T-MPneMM*8ou#Mg>}L9`>2WS} z&UxdRwgaX^Xa<}w(O9V!=MZsQW6qnf)R}0yEiDY@x+>4N@-TXQTo|Jbyl4%#1}&N; ze$Z8g%I$)iP%Nst>9*X-Tx^qr=j~tbjmcJbNTp{^o4xDhQ^8ABN`>b#cYF7^b>EQU zYH#^p27BLRBbK?MlwWqXAD$Vs)wlSoS)nUr7ITA6D`fZ5af7wCY@sBpvz$6!W$I*8 zo?)n#jHFn-8R6^nj9KaMgyOzt_h^~4+BilXRYDsS%u%w8bE!y{r}e7ozuAucZ96xc S5W;XAgnk%A{%$|sHkN<>O4t?v diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/decoder.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/decoder.cpython-38.pyc deleted file mode 100644 index 5ce2bbec7aed720ccd9a6dba85cb7ae3d7cff618..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23083 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 HvFQB|@+l{% diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/ordered.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/ordered.cpython-38.pyc deleted file mode 100644 index 166a34072eda6d24074f7d94e7410beb9b5af9df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 916 zcmb_b&2AGh5FXpR$)-s}=mjKrfgIA6XpRW=P{b`93YWcDk?o2t-XH7@2-I6E<-~*J z1$Y1+!&gpy1y0QDW~)f_gs?Q9=99hOd^4kcKb;-{o*&zva>W3C5ji{&k~0iXpg}VW z19^IhKz6Fl4+*-ZIX#CM36;TP=sSr z?W=X-iVF6Ja?+#lPZ1iphAVarH~fk>LbLDGEL^~juh4ibHCo<9A@-XZeU7A5cI~~C zA(1jK^F~U?QD(p{u8{QHTLZjU(JVMtSW1bYVxY|?b-u4`ej^9Km&91^g#38Sx8=X QJ9$NIdwM(JGck+*02F${v;Y7A diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/tz.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/_vendored/toml/__pycache__/tz.cpython-38.pyc deleted file mode 100644 index 0f645365408a9e959d7bcecaf8ac4b843fed2852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1135 zcmZuw&2AGh5VpNP*`y5(P(dp=av*|sBXOw^LP$Mu%Z2u`7i-Bl&6Ztnu$`htxwRZQ z^9+3r9%HYZ@(R7c%x+Re6iXi4GxmJnelvU8?RFTBqo2RzxnS%!9X5xLhYvXI3pBuh z=d9ofFGM0Z`^Z3mcg?_4;>t@r@ISGBu*93JFRHf73I!^6X%)J8rpM)oBAWvdo9wS~ zqgcX$B?35zYlhh{AFe(G5aJp@3nE-YXd_Ce3Qx)+Kbemx$9mA77$4)b37Q25{zaG` zhy{~OhYL>Yf}JDheFi?pUP7P+gy`oEZ($^a)_1YbuIR3}@6B#Nr$CJhR7^KH2t93k|zBo%kkJMR|V2$XS(t-?W#~t%9*iMB#TVX zoU$mMZ&f}{wj6%r>d6f=k1)|~7Ej7T#a4}sa-~-BS>~is)6&K>oyF61}^?_C9 zLYY|Ui#X3d$J0wUDfOGfqu6Fn9pJq$>6x-|W=rE@d7(6vMnO!Fv6~-GFOiVUG-j6p z0^4mgj7K~YA>ZS>e7@6E;BbBGUMZ*?bt$OF0OdSqPf0p4ti02c<32Z(^G2A5xKsjM z{e_KrOfKvjofhf=?rmLXKJTtTo5(##Vp>B!!3_aAf~C58z<-F{1|9_t8qHg4$$its z7lu&G4w)Vq%JMI%_RNi%DiZBAuilE+UGN^YJ2fJF=1`9-UTabJ4r)vlJw zIx8r25Bn{u5{V>b)seC&VV2W=TgtDqG;bn?o|`=~&&WI{L*2AtNN_{_O4AZYEOk5b nBCqxi`+gNc>J 1 and n[0] == "0" and n[1] != ".": - return False - if "__" in n: - return False - return True - - -def load(f, _dict=dict, decoder=None): - """Parses named file or files as toml and returns a dictionary - - Args: - f: Path to the file to open, array of files to read into single dict - or a file descriptor - _dict: (optional) Specifies the class of the returned toml dictionary - decoder: The decoder to use - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError -- When f is invalid type - TomlDecodeError: Error while decoding toml - IOError / FileNotFoundError -- When an array with no valid (existing) - (Python 2 / Python 3) file paths is passed - """ - - if _ispath(f): - with io.open(_getpath(f), encoding="utf-8") as ffile: - return loads(ffile.read(), _dict, decoder) - elif isinstance(f, list): - from os import path as op - from warnings import warn - - if not [path for path in f if op.exists(path)]: - error_msg = "Load expects a list to contain filenames only." - error_msg += linesep - error_msg += "The list needs to contain the path of at least one " "existing file." - raise FNFError(error_msg) - if decoder is None: - decoder = TomlDecoder(_dict) - d = decoder.get_empty_table() - for l in f: # noqa: E741 - if op.exists(l): - d.update(load(l, _dict, decoder)) - else: - warn("Non-existent filename in list with at least one valid " "filename") - return d - else: - try: - return loads(f.read(), _dict, decoder) - except AttributeError: - raise TypeError("You can only load a file descriptor, filename or " "list") - - -_groupname_re = re.compile(r"^[A-Za-z0-9_-]+$") - - -def loads(s, _dict=dict, decoder=None): - """Parses string as toml - - Args: - s: String to be parsed - _dict: (optional) Specifies the class of the returned toml dictionary - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError: When a non-string is passed - TomlDecodeError: Error while decoding toml - """ - - implicitgroups = [] - if decoder is None: - decoder = TomlDecoder(_dict) - retval = decoder.get_empty_table() - currentlevel = retval - if not isinstance(s, basestring): - raise TypeError("Expecting something like a string") - - if not isinstance(s, unicode): - s = s.decode("utf8") - - original = s - sl = list(s) - openarr = 0 - openstring = False - openstrchar = "" - multilinestr = False - arrayoftables = False - beginline = True - keygroup = False - dottedkey = False - keyname = 0 - key = "" - prev_key = "" - line_no = 1 - - for i, item in enumerate(sl): - if item == "\r" and sl[i + 1] == "\n": - sl[i] = " " - continue - if keyname: - key += item - if item == "\n": - raise TomlDecodeError( - "Key name found without value." " Reached end of line.", original, i - ) - if openstring: - if item == openstrchar: - oddbackslash = False - k = 1 - while i >= k and sl[i - k] == "\\": - oddbackslash = not oddbackslash - k += 1 - if not oddbackslash: - keyname = 2 - openstring = False - openstrchar = "" - continue - elif keyname == 1: - if item.isspace(): - keyname = 2 - continue - elif item == ".": - dottedkey = True - continue - elif item.isalnum() or item == "_" or item == "-": - continue - elif dottedkey and sl[i - 1] == "." and (item == '"' or item == "'"): - openstring = True - openstrchar = item - continue - elif keyname == 2: - if item.isspace(): - if dottedkey: - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != ".": - keyname = 1 - continue - if item == ".": - dottedkey = True - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != ".": - keyname = 1 - continue - if item == "=": - keyname = 0 - prev_key = key[:-1].rstrip() - key = "" - dottedkey = False - else: - raise TomlDecodeError( - "Found invalid character in key name: '" - + item - + "'. Try quoting the key name.", - original, - i, - ) - if item == "'" and openstrchar != '"': - k = 1 - try: - while sl[i - k] == "'": - k += 1 - if k == 3: - break - except IndexError: - pass - if k == 3: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = "'" - else: - openstrchar = "" - if item == '"' and openstrchar != "'": - oddbackslash = False - k = 1 - tripquote = False - try: - while sl[i - k] == '"': - k += 1 - if k == 3: - tripquote = True - break - if k == 1 or (k == 3 and tripquote): - while sl[i - k] == "\\": - oddbackslash = not oddbackslash - k += 1 - except IndexError: - pass - if not oddbackslash: - if tripquote: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = '"' - else: - openstrchar = "" - if item == "#" and (not openstring and not keygroup and not arrayoftables): - j = i - comment = "" - try: - while sl[j] != "\n": - comment += s[j] - sl[j] = " " - j += 1 - except IndexError: - break - if not openarr: - decoder.preserve_comment(line_no, prev_key, comment, beginline) - if item == "[" and (not openstring and not keygroup and not arrayoftables): - if beginline: - if len(sl) > i + 1 and sl[i + 1] == "[": - arrayoftables = True - else: - keygroup = True - else: - openarr += 1 - if item == "]" and not openstring: - if keygroup: - keygroup = False - elif arrayoftables: - if sl[i - 1] == "]": - arrayoftables = False - else: - openarr -= 1 - if item == "\n": - if openstring or multilinestr: - if not multilinestr: - raise TomlDecodeError("Unbalanced quotes", original, i) - if (sl[i - 1] == "'" or sl[i - 1] == '"') and (sl[i - 2] == sl[i - 1]): - sl[i] = sl[i - 1] - if sl[i - 3] == sl[i - 1]: - sl[i - 3] = " " - elif openarr: - sl[i] = " " - else: - beginline = True - line_no += 1 - elif beginline and sl[i] != " " and sl[i] != "\t": - beginline = False - if not keygroup and not arrayoftables: - if sl[i] == "=": - raise TomlDecodeError("Found empty keyname. ", original, i) - keyname = 1 - key += item - if keyname: - raise TomlDecodeError( - "Key name found without value." " Reached end of file.", original, len(s) - ) - if openstring: # reached EOF and have an unterminated string - raise TomlDecodeError( - "Unterminated string found." " Reached end of file.", original, len(s) - ) - s = "".join(sl) - s = s.split("\n") - multikey = None - multilinestr = "" - multibackslash = False - pos = 0 - for idx, line in enumerate(s): - if idx > 0: - pos += len(s[idx - 1]) + 1 - - decoder.embed_comments(idx, currentlevel) - - if not multilinestr or multibackslash or "\n" not in multilinestr: - line = line.strip() - if line == "" and (not multikey or multibackslash): - continue - if multikey: - if multibackslash: - multilinestr += line - else: - multilinestr += line - multibackslash = False - closed = False - if multilinestr[0] == "[": - closed = line[-1] == "]" - elif len(line) > 2: - closed = ( - line[-1] == multilinestr[0] - and line[-2] == multilinestr[0] - and line[-3] == multilinestr[0] - ) - if closed: - try: - value, vtype = decoder.load_value(multilinestr) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - currentlevel[multikey] = value - multikey = None - multilinestr = "" - else: - k = len(multilinestr) - 1 - while k > -1 and multilinestr[k] == "\\": - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = multilinestr[:-1] - else: - multilinestr += "\n" - continue - if line[0] == "[": - arrayoftables = False - if len(line) == 1: - raise TomlDecodeError( - "Opening key group bracket on line by " "itself.", original, pos - ) - if line[1] == "[": - arrayoftables = True - line = line[2:] - splitstr = "]]" - else: - line = line[1:] - splitstr = "]" - i = 1 - quotesplits = decoder._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and splitstr in quotesplit: - break - i += quotesplit.count(splitstr) - quoted = not quoted - line = line.split(splitstr, i) - if len(line) < i + 1 or line[-1].strip() != "": - raise TomlDecodeError("Key group not on a line by itself.", original, pos) - groups = splitstr.join(line[:-1]).split(".") - i = 0 - while i < len(groups): - groups[i] = groups[i].strip() - if len(groups[i]) > 0 and (groups[i][0] == '"' or groups[i][0] == "'"): - groupstr = groups[i] - j = i + 1 - while not groupstr[0] == groupstr[-1]: - j += 1 - if j > len(groups) + 2: - raise TomlDecodeError( - "Invalid group name '" + groupstr + "' Something " + "went wrong.", - original, - pos, - ) - groupstr = ".".join(groups[i:j]).strip() - groups[i] = groupstr[1:-1] - groups[i + 1 : j] = [] - else: - if not _groupname_re.match(groups[i]): - raise TomlDecodeError( - "Invalid group name '" + groups[i] + "'. Try quoting it.", original, pos - ) - i += 1 - currentlevel = retval - for i in _range(len(groups)): - group = groups[i] - if group == "": - raise TomlDecodeError( - "Can't have a keygroup with an empty " "name", original, pos - ) - try: - currentlevel[group] - if i == len(groups) - 1: - if group in implicitgroups: - implicitgroups.remove(group) - if arrayoftables: - raise TomlDecodeError( - "An implicitly defined " "table can't be an array", - original, - pos, - ) - elif arrayoftables: - currentlevel[group].append(decoder.get_empty_table()) - else: - raise TomlDecodeError( - "What? " + group + " already exists?" + str(currentlevel), - original, - pos, - ) - except TypeError: - currentlevel = currentlevel[-1] - if group not in currentlevel: - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - except KeyError: - if i != len(groups) - 1: - implicitgroups.append(group) - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - currentlevel = currentlevel[group] - if arrayoftables: - try: - currentlevel = currentlevel[-1] - except KeyError: - pass - elif line[0] == "{": - if line[-1] != "}": - raise TomlDecodeError( - "Line breaks are not allowed in inline" "objects", original, pos - ) - try: - decoder.load_inline_object(line, currentlevel, multikey, multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - elif "=" in line: - try: - ret = decoder.load_line(line, currentlevel, multikey, multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - if ret is not None: - multikey, multilinestr, multibackslash = ret - return retval - - -def _load_date(val): - microsecond = 0 - tz = None - try: - if len(val) > 19: - if val[19] == ".": - if val[-1].upper() == "Z": - subsecondval = val[20:-1] - tzval = "Z" - else: - subsecondvalandtz = val[20:] - if "+" in subsecondvalandtz: - splitpoint = subsecondvalandtz.index("+") - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - elif "-" in subsecondvalandtz: - splitpoint = subsecondvalandtz.index("-") - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - else: - tzval = None - subsecondval = subsecondvalandtz - if tzval is not None: - tz = TomlTz(tzval) - microsecond = int(int(subsecondval) * (10 ** (6 - len(subsecondval)))) - else: - tz = TomlTz(val[19:]) - except ValueError: - tz = None - if "-" not in val[1:]: - return None - try: - if len(val) == 10: - d = datetime.date(int(val[:4]), int(val[5:7]), int(val[8:10])) - else: - d = datetime.datetime( - int(val[:4]), - int(val[5:7]), - int(val[8:10]), - int(val[11:13]), - int(val[14:16]), - int(val[17:19]), - microsecond, - tz, - ) - except ValueError: - return None - return d - - -def _load_unicode_escapes(v, hexbytes, prefix): - skip = False - i = len(v) - 1 - while i > -1 and v[i] == "\\": - skip = not skip - i -= 1 - for hx in hexbytes: - if skip: - skip = False - i = len(hx) - 1 - while i > -1 and hx[i] == "\\": - skip = not skip - i -= 1 - v += prefix - v += hx - continue - hxb = "" - i = 0 - hxblen = 4 - if prefix == "\\U": - hxblen = 8 - hxb = "".join(hx[i : i + hxblen]).lower() - if hxb.strip("0123456789abcdef"): - raise ValueError("Invalid escape sequence: " + hxb) - if hxb[0] == "d" and hxb[1].strip("01234567"): - raise ValueError( - "Invalid escape sequence: " + hxb + ". Only scalar unicode points are allowed." - ) - v += unichr(int(hxb, 16)) - v += unicode(hx[len(hxb) :]) - return v - - -# Unescape TOML string values. - -# content after the \ -_escapes = ["0", "b", "f", "n", "r", "t", '"'] -# What it should be replaced by -_escapedchars = ["\0", "\b", "\f", "\n", "\r", "\t", '"'] -# Used for substitution -_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) - - -def _unescape(v): - """Unescape characters in a TOML string.""" - i = 0 - backslash = False - while i < len(v): - if backslash: - backslash = False - if v[i] in _escapes: - v = v[: i - 1] + _escape_to_escapedchars[v[i]] + v[i + 1 :] - elif v[i] == "\\": - v = v[: i - 1] + v[i:] - elif v[i] == "u" or v[i] == "U": - i += 1 - else: - raise ValueError("Reserved escape sequence used") - continue - elif v[i] == "\\": - backslash = True - i += 1 - return v - - -class InlineTableDict(object): - """Sentinel subclass of dict for inline tables.""" - - -class TomlDecoder(object): - def __init__(self, _dict=dict): - self._dict = _dict - - def get_empty_table(self): - return self._dict() - - def get_empty_inline_table(self): - class DynamicInlineTableDict(self._dict, InlineTableDict): - """Concrete sentinel subclass for inline tables. - It is a subclass of _dict which is passed in dynamically at load - time - - It is also a subclass of InlineTableDict - """ - - return DynamicInlineTableDict() - - def load_inline_object(self, line, currentlevel, multikey=False, multibackslash=False): - candidate_groups = line[1:-1].split(",") - groups = [] - if len(candidate_groups) == 1 and not candidate_groups[0].strip(): - candidate_groups.pop() - while len(candidate_groups) > 0: - candidate_group = candidate_groups.pop(0) - try: - _, value = candidate_group.split("=", 1) - except ValueError: - raise ValueError("Invalid inline table encountered") - value = value.strip() - if (value[0] == value[-1] and value[0] in ('"', "'")) or ( - value[0] in "-0123456789" - or value in ("true", "false") - or (value[0] == "[" and value[-1] == "]") - or (value[0] == "{" and value[-1] == "}") - ): - groups.append(candidate_group) - elif len(candidate_groups) > 0: - candidate_groups[0] = candidate_group + "," + candidate_groups[0] - else: - raise ValueError("Invalid inline table value encountered") - for group in groups: - status = self.load_line(group, currentlevel, multikey, multibackslash) - if status is not None: - break - - def _get_split_on_quotes(self, line): - doublequotesplits = line.split('"') - quoted = False - quotesplits = [] - if len(doublequotesplits) > 1 and "'" in doublequotesplits[0]: - singlequotesplits = doublequotesplits[0].split("'") - doublequotesplits = doublequotesplits[1:] - while len(singlequotesplits) % 2 == 0 and len(doublequotesplits): - singlequotesplits[-1] += '"' + doublequotesplits[0] - doublequotesplits = doublequotesplits[1:] - if "'" in singlequotesplits[-1]: - singlequotesplits = singlequotesplits[:-1] + singlequotesplits[-1].split("'") - quotesplits += singlequotesplits - for doublequotesplit in doublequotesplits: - if quoted: - quotesplits.append(doublequotesplit) - else: - quotesplits += doublequotesplit.split("'") - quoted = not quoted - return quotesplits - - def load_line(self, line, currentlevel, multikey, multibackslash): - i = 1 - quotesplits = self._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and "=" in quotesplit: - break - i += quotesplit.count("=") - quoted = not quoted - pair = line.split("=", i) - strictly_valid = _strictly_valid_num(pair[-1]) - if _number_with_underscores.match(pair[-1]): - pair[-1] = pair[-1].replace("_", "") - while len(pair[-1]) and ( - pair[-1][0] != " " - and pair[-1][0] != "\t" - and pair[-1][0] != "'" - and pair[-1][0] != '"' - and pair[-1][0] != "[" - and pair[-1][0] != "{" - and pair[-1].strip() != "true" - and pair[-1].strip() != "false" - ): - try: - float(pair[-1]) - break - except ValueError: - pass - if _load_date(pair[-1]) is not None: - break - if TIME_RE.match(pair[-1]): - break - i += 1 - prev_val = pair[-1] - pair = line.split("=", i) - if prev_val == pair[-1]: - raise ValueError("Invalid date or number") - if strictly_valid: - strictly_valid = _strictly_valid_num(pair[-1]) - pair = ["=".join(pair[:-1]).strip(), pair[-1].strip()] - if "." in pair[0]: - if '"' in pair[0] or "'" in pair[0]: - quotesplits = self._get_split_on_quotes(pair[0]) - quoted = False - levels = [] - for quotesplit in quotesplits: - if quoted: - levels.append(quotesplit) - else: - levels += [level.strip() for level in quotesplit.split(".")] - quoted = not quoted - else: - levels = pair[0].split(".") - while levels[-1] == "": - levels = levels[:-1] - for level in levels[:-1]: - if level == "": - continue - if level not in currentlevel: - currentlevel[level] = self.get_empty_table() - currentlevel = currentlevel[level] - pair[0] = levels[-1].strip() - elif (pair[0][0] == '"' or pair[0][0] == "'") and (pair[0][-1] == pair[0][0]): - pair[0] = _unescape(pair[0][1:-1]) - k, koffset = self._load_line_multiline_str(pair[1]) - if k > -1: - while k > -1 and pair[1][k + koffset] == "\\": - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = pair[1][:-1] - else: - multilinestr = pair[1] + "\n" - multikey = pair[0] - else: - value, vtype = self.load_value(pair[1], strictly_valid) - try: - currentlevel[pair[0]] - raise ValueError("Duplicate keys!") - except TypeError: - raise ValueError("Duplicate keys!") - except KeyError: - if multikey: - return multikey, multilinestr, multibackslash - else: - currentlevel[pair[0]] = value - - def _load_line_multiline_str(self, p): - poffset = 0 - if len(p) < 3: - return -1, poffset - if p[0] == "[" and (p.strip()[-1] != "]" and self._load_array_isstrarray(p)): - newp = p[1:].strip().split(",") - while len(newp) > 1 and newp[-1][0] != '"' and newp[-1][0] != "'": - newp = newp[:-2] + [newp[-2] + "," + newp[-1]] - newp = newp[-1] - poffset = len(p) - len(newp) - p = newp - if p[0] != '"' and p[0] != "'": - return -1, poffset - if p[1] != p[0] or p[2] != p[0]: - return -1, poffset - if len(p) > 5 and p[-1] == p[0] and p[-2] == p[0] and p[-3] == p[0]: - return -1, poffset - return len(p) - 1, poffset - - def load_value(self, v, strictly_valid=True): - if not v: - raise ValueError("Empty value is invalid") - if v == "true": - return (True, "bool") - elif v == "false": - return (False, "bool") - elif v[0] == '"' or v[0] == "'": - quotechar = v[0] - testv = v[1:].split(quotechar) - triplequote = False - triplequotecount = 0 - if len(testv) > 1 and testv[0] == "" and testv[1] == "": - testv = testv[2:] - triplequote = True - closed = False - for tv in testv: - if tv == "": - if triplequote: - triplequotecount += 1 - else: - closed = True - else: - oddbackslash = False - try: - i = -1 - j = tv[i] - while j == "\\": - oddbackslash = not oddbackslash - i -= 1 - j = tv[i] - except IndexError: - pass - if not oddbackslash: - if closed: - raise ValueError( - "Found tokens after a closed " + "string. Invalid TOML." - ) - else: - if not triplequote or triplequotecount > 1: - closed = True - else: - triplequotecount = 0 - if quotechar == '"': - escapeseqs = v.split("\\")[1:] - backslash = False - for i in escapeseqs: - if i == "": - backslash = not backslash - else: - if i[0] not in _escapes and (i[0] != "u" and i[0] != "U" and not backslash): - raise ValueError("Reserved escape sequence used") - if backslash: - backslash = False - for prefix in ["\\u", "\\U"]: - if prefix in v: - hexbytes = v.split(prefix) - v = _load_unicode_escapes(hexbytes[0], hexbytes[1:], prefix) - v = _unescape(v) - if len(v) > 1 and v[1] == quotechar and (len(v) < 3 or v[1] == v[2]): - v = v[2:-2] - return (v[1:-1], "str") - elif v[0] == "[": - return (self.load_array(v), "array") - elif v[0] == "{": - inline_object = self.get_empty_inline_table() - self.load_inline_object(v, inline_object) - return (inline_object, "inline_object") - elif TIME_RE.match(v): - h, m, s, _, ms = TIME_RE.match(v).groups() - time = datetime.time(int(h), int(m), int(s), int(ms) if ms else 0) - return (time, "time") - else: - parsed_date = _load_date(v) - if parsed_date is not None: - return (parsed_date, "date") - if not strictly_valid: - raise ValueError("Weirdness with leading zeroes or " "underscores in your number.") - itype = "int" - neg = False - if v[0] == "-": - neg = True - v = v[1:] - elif v[0] == "+": - v = v[1:] - v = v.replace("_", "") - lowerv = v.lower() - if "." in v or ("x" not in v and ("e" in v or "E" in v)): - if "." in v and v.split(".", 1)[1] == "": - raise ValueError("This float is missing digits after " "the point") - if v[0] not in "0123456789": - raise ValueError("This float doesn't have a leading " "digit") - v = float(v) - itype = "float" - elif len(lowerv) == 3 and (lowerv == "inf" or lowerv == "nan"): - v = float(v) - itype = "float" - if itype == "int": - v = int(v, 0) - if neg: - return (0 - v, itype) - return (v, itype) - - def bounded_string(self, s): - if len(s) == 0: - return True - if s[-1] != s[0]: - return False - i = -2 - backslash = False - while len(s) + i > 0: - if s[i] == "\\": - backslash = not backslash - i -= 1 - else: - break - return not backslash - - def _load_array_isstrarray(self, a): - a = a[1:-1].strip() - if a != "" and (a[0] == '"' or a[0] == "'"): - return True - return False - - def load_array(self, a): - atype = None - retval = [] - a = a.strip() - if "[" not in a[1:-1] or "" != a[1:-1].split("[")[0].strip(): - strarray = self._load_array_isstrarray(a) - if not a[1:-1].strip().startswith("{"): - a = a[1:-1].split(",") - else: - # a is an inline object, we must find the matching parenthesis - # to define groups - new_a = [] - start_group_index = 1 - end_group_index = 2 - open_bracket_count = 1 if a[start_group_index] == "{" else 0 - in_str = False - while end_group_index < len(a[1:]): - if a[end_group_index] == '"' or a[end_group_index] == "'": - if in_str: - backslash_index = end_group_index - 1 - while backslash_index > -1 and a[backslash_index] == "\\": - in_str = not in_str - backslash_index -= 1 - in_str = not in_str - if not in_str and a[end_group_index] == "{": - open_bracket_count += 1 - if in_str or a[end_group_index] != "}": - end_group_index += 1 - continue - elif a[end_group_index] == "}" and open_bracket_count > 1: - open_bracket_count -= 1 - end_group_index += 1 - continue - - # Increase end_group_index by 1 to get the closing bracket - end_group_index += 1 - - new_a.append(a[start_group_index:end_group_index]) - - # The next start index is at least after the closing - # bracket, a closing bracket can be followed by a comma - # since we are in an array. - start_group_index = end_group_index + 1 - while start_group_index < len(a[1:]) and a[start_group_index] != "{": - start_group_index += 1 - end_group_index = start_group_index + 1 - a = new_a - b = 0 - if strarray: - while b < len(a) - 1: - ab = a[b].strip() - while not self.bounded_string(ab) or ( - len(ab) > 2 - and ab[0] == ab[1] == ab[2] - and ab[-2] != ab[0] - and ab[-3] != ab[0] - ): - a[b] = a[b] + "," + a[b + 1] - ab = a[b].strip() - if b < len(a) - 2: - a = a[: b + 1] + a[b + 2 :] - else: - a = a[: b + 1] - b += 1 - else: - al = list(a[1:-1]) - a = [] - openarr = 0 - j = 0 - for i in _range(len(al)): - if al[i] == "[": - openarr += 1 - elif al[i] == "]": - openarr -= 1 - elif al[i] == "," and not openarr: - a.append("".join(al[j:i])) - j = i + 1 - a.append("".join(al[j:])) - for i in _range(len(a)): - a[i] = a[i].strip() - if a[i] != "": - nval, ntype = self.load_value(a[i]) - if atype: - if ntype != atype: - raise ValueError("Not a homogeneous array") - else: - atype = ntype - retval.append(nval) - return retval - - def preserve_comment(self, line_no, key, comment, beginline): - pass - - def embed_comments(self, idx, currentlevel): - pass - - -class TomlPreserveCommentDecoder(TomlDecoder): - def __init__(self, _dict=dict): - self.saved_comments = {} - super(TomlPreserveCommentDecoder, self).__init__(_dict) - - def preserve_comment(self, line_no, key, comment, beginline): - self.saved_comments[line_no] = (key, comment, beginline) - - def embed_comments(self, idx, currentlevel): - if idx not in self.saved_comments: - return - - key, comment, beginline = self.saved_comments[idx] - currentlevel[key] = CommentValue(currentlevel[key], comment, beginline, self._dict) diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/encoder.py b/env/lib/python3.8/site-packages/isort/_vendored/toml/encoder.py deleted file mode 100644 index 68ec60f9..00000000 --- a/env/lib/python3.8/site-packages/isort/_vendored/toml/encoder.py +++ /dev/null @@ -1,295 +0,0 @@ -import datetime -import re -import sys -from decimal import Decimal - -from .decoder import InlineTableDict - -if sys.version_info >= (3,): - unicode = str - - -def dump(o, f, encoder=None): - """Writes out dict as toml to a file - - Args: - o: Object to dump into toml - f: File descriptor where the toml should be stored - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dictionary - - Raises: - TypeError: When anything other than file descriptor is passed - """ - - if not f.write: - raise TypeError("You can only dump an object to a file descriptor") - d = dumps(o, encoder=encoder) - f.write(d) - return d - - -def dumps(o, encoder=None): - """Stringifies input dict as toml - - Args: - o: Object to dump into toml - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dict - - Examples: - ```python - >>> import toml - >>> output = { - ... 'a': "I'm a string", - ... 'b': ["I'm", "a", "list"], - ... 'c': 2400 - ... } - >>> toml.dumps(output) - 'a = "I\'m a string"\nb = [ "I\'m", "a", "list",]\nc = 2400\n' - ``` - """ - - retval = "" - if encoder is None: - encoder = TomlEncoder(o.__class__) - addtoretval, sections = encoder.dump_sections(o, "") - retval += addtoretval - outer_objs = [id(o)] - while sections: - section_ids = [id(section) for section in sections] - for outer_obj in outer_objs: - if outer_obj in section_ids: - raise ValueError("Circular reference detected") - outer_objs += section_ids - newsections = encoder.get_empty_table() - for section in sections: - addtoretval, addtosections = encoder.dump_sections(sections[section], section) - - if addtoretval or (not addtoretval and not addtosections): - if retval and retval[-2:] != "\n\n": - retval += "\n" - retval += "[" + section + "]\n" - if addtoretval: - retval += addtoretval - for s in addtosections: - newsections[section + "." + s] = addtosections[s] - sections = newsections - return retval - - -def _dump_str(v): - if sys.version_info < (3,) and hasattr(v, "decode") and isinstance(v, str): - v = v.decode("utf-8") - v = "%r" % v - if v[0] == "u": - v = v[1:] - singlequote = v.startswith("'") - if singlequote or v.startswith('"'): - v = v[1:-1] - if singlequote: - v = v.replace("\\'", "'") - v = v.replace('"', '\\"') - v = v.split("\\x") - while len(v) > 1: - i = -1 - if not v[0]: - v = v[1:] - v[0] = v[0].replace("\\\\", "\\") - # No, I don't know why != works and == breaks - joinx = v[0][i] != "\\" - while v[0][:i] and v[0][i] == "\\": - joinx = not joinx - i -= 1 - if joinx: - joiner = "x" - else: - joiner = "u00" - v = [v[0] + joiner + v[1]] + v[2:] - return unicode('"' + v[0] + '"') - - -def _dump_float(v): - return "{}".format(v).replace("e+0", "e+").replace("e-0", "e-") - - -def _dump_time(v): - utcoffset = v.utcoffset() - if utcoffset is None: - return v.isoformat() - # The TOML norm specifies that it's local time thus we drop the offset - return v.isoformat()[:-6] - - -class TomlEncoder(object): - def __init__(self, _dict=dict, preserve=False): - self._dict = _dict - self.preserve = preserve - self.dump_funcs = { - str: _dump_str, - unicode: _dump_str, - list: self.dump_list, - bool: lambda v: unicode(v).lower(), - int: lambda v: v, - float: _dump_float, - Decimal: _dump_float, - datetime.datetime: lambda v: v.isoformat().replace("+00:00", "Z"), - datetime.time: _dump_time, - datetime.date: lambda v: v.isoformat(), - } - - def get_empty_table(self): - return self._dict() - - def dump_list(self, v): - retval = "[" - for u in v: - retval += " " + unicode(self.dump_value(u)) + "," - retval += "]" - return retval - - def dump_inline_table(self, section): - """Preserve inline table in its compact syntax instead of expanding - into subsection. - - https://github.com/toml-lang/toml#user-content-inline-table - """ - retval = "" - if isinstance(section, dict): - val_list = [] - for k, v in section.items(): - val = self.dump_inline_table(v) - val_list.append(k + " = " + val) - retval += "{ " + ", ".join(val_list) + " }\n" - return retval - else: - return unicode(self.dump_value(section)) - - def dump_value(self, v): - # Lookup function corresponding to v's type - dump_fn = self.dump_funcs.get(type(v)) - if dump_fn is None and hasattr(v, "__iter__"): - dump_fn = self.dump_funcs[list] - # Evaluate function (if it exists) else return v - return dump_fn(v) if dump_fn is not None else self.dump_funcs[str](v) - - def dump_sections(self, o, sup): - retstr = "" - if sup != "" and sup[-1] != ".": - sup += "." - retdict = self._dict() - arraystr = "" - for section in o: - section = unicode(section) - qsection = section - if not re.match(r"^[A-Za-z0-9_-]+$", section): - qsection = _dump_str(section) - if not isinstance(o[section], dict): - arrayoftables = False - if isinstance(o[section], list): - for a in o[section]: - if isinstance(a, dict): - arrayoftables = True - if arrayoftables: - for a in o[section]: - arraytabstr = "\n" - arraystr += "[[" + sup + qsection + "]]\n" - s, d = self.dump_sections(a, sup + qsection) - if s: - if s[0] == "[": - arraytabstr += s - else: - arraystr += s - while d: - newd = self._dict() - for dsec in d: - s1, d1 = self.dump_sections(d[dsec], sup + qsection + "." + dsec) - if s1: - arraytabstr += "[" + sup + qsection + "." + dsec + "]\n" - arraytabstr += s1 - for s1 in d1: - newd[dsec + "." + s1] = d1[s1] - d = newd - arraystr += arraytabstr - else: - if o[section] is not None: - retstr += qsection + " = " + unicode(self.dump_value(o[section])) + "\n" - elif self.preserve and isinstance(o[section], InlineTableDict): - retstr += qsection + " = " + self.dump_inline_table(o[section]) - else: - retdict[qsection] = o[section] - retstr += arraystr - return (retstr, retdict) - - -class TomlPreserveInlineDictEncoder(TomlEncoder): - def __init__(self, _dict=dict): - super(TomlPreserveInlineDictEncoder, self).__init__(_dict, True) - - -class TomlArraySeparatorEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False, separator=","): - super(TomlArraySeparatorEncoder, self).__init__(_dict, preserve) - if separator.strip() == "": - separator = "," + separator - elif separator.strip(" \t\n\r,"): - raise ValueError("Invalid separator for arrays") - self.separator = separator - - def dump_list(self, v): - t = [] - retval = "[" - for u in v: - t.append(self.dump_value(u)) - while t != []: - s = [] - for u in t: - if isinstance(u, list): - for r in u: - s.append(r) - else: - retval += " " + unicode(u) + self.separator - t = s - retval += "]" - return retval - - -class TomlNumpyEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False): - import numpy as np - - super(TomlNumpyEncoder, self).__init__(_dict, preserve) - self.dump_funcs[np.float16] = _dump_float - self.dump_funcs[np.float32] = _dump_float - self.dump_funcs[np.float64] = _dump_float - self.dump_funcs[np.int16] = self._dump_int - self.dump_funcs[np.int32] = self._dump_int - self.dump_funcs[np.int64] = self._dump_int - - def _dump_int(self, v): - return "{}".format(int(v)) - - -class TomlPreserveCommentEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False): - from toml.decoder import CommentValue - - super(TomlPreserveCommentEncoder, self).__init__(_dict, preserve) - self.dump_funcs[CommentValue] = lambda v: v.dump(self.dump_value) - - -class TomlPathlibEncoder(TomlEncoder): - def _dump_pathlib_path(self, v): - return _dump_str(str(v)) - - def dump_value(self, v): - if (3, 4) <= sys.version_info: - import pathlib - - if isinstance(v, pathlib.PurePath): - v = str(v) - return super(TomlPathlibEncoder, self).dump_value(v) diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/ordered.py b/env/lib/python3.8/site-packages/isort/_vendored/toml/ordered.py deleted file mode 100644 index 013b31e5..00000000 --- a/env/lib/python3.8/site-packages/isort/_vendored/toml/ordered.py +++ /dev/null @@ -1,13 +0,0 @@ -from collections import OrderedDict - -from . import TomlDecoder, TomlEncoder - - -class TomlOrderedDecoder(TomlDecoder): - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) - - -class TomlOrderedEncoder(TomlEncoder): - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) diff --git a/env/lib/python3.8/site-packages/isort/_vendored/toml/tz.py b/env/lib/python3.8/site-packages/isort/_vendored/toml/tz.py deleted file mode 100644 index 46214bd4..00000000 --- a/env/lib/python3.8/site-packages/isort/_vendored/toml/tz.py +++ /dev/null @@ -1,21 +0,0 @@ -from datetime import timedelta, tzinfo - - -class TomlTz(tzinfo): - def __init__(self, toml_offset): - if toml_offset == "Z": - self._raw_offset = "+00:00" - else: - self._raw_offset = toml_offset - self._sign = -1 if self._raw_offset[0] == "-" else 1 - self._hours = int(self._raw_offset[1:3]) - self._minutes = int(self._raw_offset[4:6]) - - def tzname(self, dt): - return "UTC" + self._raw_offset - - def utcoffset(self, dt): - return self._sign * timedelta(hours=self._hours, minutes=self._minutes) - - def dst(self, dt): - return timedelta(0) diff --git a/env/lib/python3.8/site-packages/isort/_version.py b/env/lib/python3.8/site-packages/isort/_version.py deleted file mode 100644 index f0b716b2..00000000 --- a/env/lib/python3.8/site-packages/isort/_version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "5.6.4" diff --git a/env/lib/python3.8/site-packages/isort/api.py b/env/lib/python3.8/site-packages/isort/api.py deleted file mode 100644 index 5a2df6af..00000000 --- a/env/lib/python3.8/site-packages/isort/api.py +++ /dev/null @@ -1,389 +0,0 @@ -import shutil -import sys -from io import StringIO -from pathlib import Path -from typing import Optional, TextIO, Union, cast -from warnings import warn - -from isort import core - -from . import io -from .exceptions import ( - ExistingSyntaxErrors, - FileSkipComment, - FileSkipSetting, - IntroducedSyntaxErrors, -) -from .format import ask_whether_to_apply_changes_to_file, create_terminal_printer, show_unified_diff -from .io import Empty -from .place import module as place_module # noqa: F401 -from .place import module_with_reason as place_module_with_reason # noqa: F401 -from .settings import DEFAULT_CONFIG, Config - - -def sort_code_string( - code: str, - extension: Optional[str] = None, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = False, - show_diff: Union[bool, TextIO] = False, - **config_kwargs, -): - """Sorts any imports within the provided code string, returning a new string with them sorted. - - - **code**: The string of code with imports that need to be sorted. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - ****config_kwargs**: Any config modifications. - """ - input_stream = StringIO(code) - output_stream = StringIO() - config = _config(path=file_path, config=config, **config_kwargs) - sort_stream( - input_stream, - output_stream, - extension=extension, - config=config, - file_path=file_path, - disregard_skip=disregard_skip, - show_diff=show_diff, - ) - output_stream.seek(0) - return output_stream.read() - - -def check_code_string( - code: str, - show_diff: Union[bool, TextIO] = False, - extension: Optional[str] = None, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = False, - **config_kwargs, -) -> bool: - """Checks the order, format, and categorization of imports within the provided code string. - Returns `True` if everything is correct, otherwise `False`. - - - **code**: The string of code with imports that need to be sorted. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - ****config_kwargs**: Any config modifications. - """ - config = _config(path=file_path, config=config, **config_kwargs) - return check_stream( - StringIO(code), - show_diff=show_diff, - extension=extension, - config=config, - file_path=file_path, - disregard_skip=disregard_skip, - ) - - -def sort_stream( - input_stream: TextIO, - output_stream: TextIO, - extension: Optional[str] = None, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = False, - show_diff: Union[bool, TextIO] = False, - **config_kwargs, -) -> bool: - """Sorts any imports within the provided code stream, outputs to the provided output stream. - Returns `True` if anything is modified from the original input stream, otherwise `False`. - - - **input_stream**: The stream of code with imports that need to be sorted. - - **output_stream**: The stream where sorted imports should be written to. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - ****config_kwargs**: Any config modifications. - """ - if show_diff: - _output_stream = StringIO() - _input_stream = StringIO(input_stream.read()) - changed = sort_stream( - input_stream=_input_stream, - output_stream=_output_stream, - extension=extension, - config=config, - file_path=file_path, - disregard_skip=disregard_skip, - **config_kwargs, - ) - _output_stream.seek(0) - _input_stream.seek(0) - show_unified_diff( - file_input=_input_stream.read(), - file_output=_output_stream.read(), - file_path=file_path, - output=output_stream if show_diff is True else cast(TextIO, show_diff), - color_output=config.color_output, - ) - return changed - - config = _config(path=file_path, config=config, **config_kwargs) - content_source = str(file_path or "Passed in content") - if not disregard_skip: - if file_path and config.is_skipped(file_path): - raise FileSkipSetting(content_source) - - _internal_output = output_stream - - if config.atomic: - try: - file_content = input_stream.read() - compile(file_content, content_source, "exec", 0, 1) - input_stream = StringIO(file_content) - except SyntaxError: - raise ExistingSyntaxErrors(content_source) - - if not output_stream.readable(): - _internal_output = StringIO() - - try: - changed = core.process( - input_stream, - _internal_output, - extension=extension or (file_path and file_path.suffix.lstrip(".")) or "py", - config=config, - ) - except FileSkipComment: - raise FileSkipComment(content_source) - - if config.atomic: - _internal_output.seek(0) - try: - compile(_internal_output.read(), content_source, "exec", 0, 1) - _internal_output.seek(0) - if _internal_output != output_stream: - output_stream.write(_internal_output.read()) - except SyntaxError: # pragma: no cover - raise IntroducedSyntaxErrors(content_source) - - return changed - - -def check_stream( - input_stream: TextIO, - show_diff: Union[bool, TextIO] = False, - extension: Optional[str] = None, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = False, - **config_kwargs, -) -> bool: - """Checks any imports within the provided code stream, returning `False` if any unsorted or - incorrectly imports are found or `True` if no problems are identified. - - - **input_stream**: The stream of code with imports that need to be sorted. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - ****config_kwargs**: Any config modifications. - """ - config = _config(path=file_path, config=config, **config_kwargs) - - if show_diff: - input_stream = StringIO(input_stream.read()) - - changed: bool = sort_stream( - input_stream=input_stream, - output_stream=Empty, - extension=extension, - config=config, - file_path=file_path, - disregard_skip=disregard_skip, - ) - printer = create_terminal_printer(color=config.color_output) - if not changed: - if config.verbose and not config.only_modified: - printer.success(f"{file_path or ''} Everything Looks Good!") - return True - else: - printer.error(f"{file_path or ''} Imports are incorrectly sorted and/or formatted.") - if show_diff: - output_stream = StringIO() - input_stream.seek(0) - file_contents = input_stream.read() - sort_stream( - input_stream=StringIO(file_contents), - output_stream=output_stream, - extension=extension, - config=config, - file_path=file_path, - disregard_skip=disregard_skip, - ) - output_stream.seek(0) - - show_unified_diff( - file_input=file_contents, - file_output=output_stream.read(), - file_path=file_path, - output=None if show_diff is True else cast(TextIO, show_diff), - color_output=config.color_output, - ) - return False - - -def check_file( - filename: Union[str, Path], - show_diff: Union[bool, TextIO] = False, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = True, - extension: Optional[str] = None, - **config_kwargs, -) -> bool: - """Checks any imports within the provided file, returning `False` if any unsorted or - incorrectly imports are found or `True` if no problems are identified. - - - **filename**: The name or Path of the file to check. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - ****config_kwargs**: Any config modifications. - """ - with io.File.read(filename) as source_file: - return check_stream( - source_file.stream, - show_diff=show_diff, - extension=extension, - config=config, - file_path=file_path or source_file.path, - disregard_skip=disregard_skip, - **config_kwargs, - ) - - -def sort_file( - filename: Union[str, Path], - extension: Optional[str] = None, - config: Config = DEFAULT_CONFIG, - file_path: Optional[Path] = None, - disregard_skip: bool = True, - ask_to_apply: bool = False, - show_diff: Union[bool, TextIO] = False, - write_to_stdout: bool = False, - **config_kwargs, -) -> bool: - """Sorts and formats any groups of imports imports within the provided file or Path. - Returns `True` if the file has been changed, otherwise `False`. - - - **filename**: The name or Path of the file to format. - - **extension**: The file extension that contains imports. Defaults to filename extension or py. - - **config**: The config object to use when sorting imports. - - **file_path**: The disk location where the code string was pulled from. - - **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file. - - **ask_to_apply**: If `True`, prompt before applying any changes. - - **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a - TextIO stream is provided results will be written to it, otherwise no diff will be computed. - - **write_to_stdout**: If `True`, write to stdout instead of the input file. - - ****config_kwargs**: Any config modifications. - """ - with io.File.read(filename) as source_file: - actual_file_path = file_path or source_file.path - config = _config(path=actual_file_path, config=config, **config_kwargs) - changed: bool = False - try: - if write_to_stdout: - changed = sort_stream( - input_stream=source_file.stream, - output_stream=sys.stdout, - config=config, - file_path=actual_file_path, - disregard_skip=disregard_skip, - extension=extension, - ) - else: - tmp_file = source_file.path.with_suffix(source_file.path.suffix + ".isorted") - try: - with tmp_file.open( - "w", encoding=source_file.encoding, newline="" - ) as output_stream: - shutil.copymode(filename, tmp_file) - changed = sort_stream( - input_stream=source_file.stream, - output_stream=output_stream, - config=config, - file_path=actual_file_path, - disregard_skip=disregard_skip, - extension=extension, - ) - if changed: - if show_diff or ask_to_apply: - source_file.stream.seek(0) - with tmp_file.open( - encoding=source_file.encoding, newline="" - ) as tmp_out: - show_unified_diff( - file_input=source_file.stream.read(), - file_output=tmp_out.read(), - file_path=actual_file_path, - output=None if show_diff is True else cast(TextIO, show_diff), - color_output=config.color_output, - ) - if show_diff or ( - ask_to_apply - and not ask_whether_to_apply_changes_to_file( - str(source_file.path) - ) - ): - return False - source_file.stream.close() - tmp_file.replace(source_file.path) - if not config.quiet: - print(f"Fixing {source_file.path}") - finally: - try: # Python 3.8+: use `missing_ok=True` instead of try except. - tmp_file.unlink() - except FileNotFoundError: - pass # pragma: no cover - except ExistingSyntaxErrors: - warn(f"{actual_file_path} unable to sort due to existing syntax errors") - except IntroducedSyntaxErrors: # pragma: no cover - warn(f"{actual_file_path} unable to sort as isort introduces new syntax errors") - - return changed - - -def _config( - path: Optional[Path] = None, config: Config = DEFAULT_CONFIG, **config_kwargs -) -> Config: - if path: - if ( - config is DEFAULT_CONFIG - and "settings_path" not in config_kwargs - and "settings_file" not in config_kwargs - ): - config_kwargs["settings_path"] = path - - if config_kwargs: - if config is not DEFAULT_CONFIG: - raise ValueError( - "You can either specify custom configuration options using kwargs or " - "passing in a Config object. Not Both!" - ) - - config = Config(**config_kwargs) - - return config diff --git a/env/lib/python3.8/site-packages/isort/comments.py b/env/lib/python3.8/site-packages/isort/comments.py deleted file mode 100644 index b865b328..00000000 --- a/env/lib/python3.8/site-packages/isort/comments.py +++ /dev/null @@ -1,32 +0,0 @@ -from typing import List, Optional, Tuple - - -def parse(line: str) -> Tuple[str, str]: - """Parses import lines for comments and returns back the - import statement and the associated comment. - """ - comment_start = line.find("#") - if comment_start != -1: - return (line[:comment_start], line[comment_start + 1 :].strip()) - - return (line, "") - - -def add_to_line( - comments: Optional[List[str]], - original_string: str = "", - removed: bool = False, - comment_prefix: str = "", -) -> str: - """Returns a string with comments added if removed is not set.""" - if removed: - return parse(original_string)[0] - - if not comments: - return original_string - else: - unique_comments: List[str] = [] - for comment in comments: - if comment not in unique_comments: - unique_comments.append(comment) - return f"{parse(original_string)[0]}{comment_prefix} {'; '.join(unique_comments)}" diff --git a/env/lib/python3.8/site-packages/isort/core.py b/env/lib/python3.8/site-packages/isort/core.py deleted file mode 100644 index 292bdc1c..00000000 --- a/env/lib/python3.8/site-packages/isort/core.py +++ /dev/null @@ -1,420 +0,0 @@ -import textwrap -from io import StringIO -from itertools import chain -from typing import List, TextIO, Union - -import isort.literal -from isort.settings import DEFAULT_CONFIG, Config - -from . import output, parse -from .exceptions import FileSkipComment -from .format import format_natural, remove_whitespace -from .settings import FILE_SKIP_COMMENTS - -CIMPORT_IDENTIFIERS = ("cimport ", "cimport*", "from.cimport") -IMPORT_START_IDENTIFIERS = ("from ", "from.import", "import ", "import*") + CIMPORT_IDENTIFIERS -COMMENT_INDICATORS = ('"""', "'''", "'", '"', "#") -CODE_SORT_COMMENTS = ( - "# isort: list", - "# isort: dict", - "# isort: set", - "# isort: unique-list", - "# isort: tuple", - "# isort: unique-tuple", - "# isort: assignments", -) - - -def process( - input_stream: TextIO, - output_stream: TextIO, - extension: str = "py", - config: Config = DEFAULT_CONFIG, -) -> bool: - """Parses stream identifying sections of contiguous imports and sorting them - - Code with unsorted imports is read from the provided `input_stream`, sorted and then - outputted to the specified `output_stream`. - - - `input_stream`: Text stream with unsorted import sections. - - `output_stream`: Text stream to output sorted inputs into. - - `config`: Config settings to use when sorting imports. Defaults settings. - - *Default*: `isort.settings.DEFAULT_CONFIG`. - - `extension`: The file extension or file extension rules that should be used. - - *Default*: `"py"`. - - *Choices*: `["py", "pyi", "pyx"]`. - - Returns `True` if there were changes that needed to be made (errors present) from what - was provided in the input_stream, otherwise `False`. - """ - line_separator: str = config.line_ending - add_imports: List[str] = [format_natural(addition) for addition in config.add_imports] - import_section: str = "" - next_import_section: str = "" - next_cimports: bool = False - in_quote: str = "" - first_comment_index_start: int = -1 - first_comment_index_end: int = -1 - contains_imports: bool = False - in_top_comment: bool = False - first_import_section: bool = True - indent: str = "" - isort_off: bool = False - code_sorting: Union[bool, str] = False - code_sorting_section: str = "" - code_sorting_indent: str = "" - cimports: bool = False - made_changes: bool = False - stripped_line: str = "" - end_of_file: bool = False - verbose_output: List[str] = [] - - if config.float_to_top: - new_input = "" - current = "" - isort_off = False - for line in chain(input_stream, (None,)): - if isort_off and line is not None: - if line == "# isort: on\n": - isort_off = False - new_input += line - elif line in ("# isort: split\n", "# isort: off\n", None) or str(line).endswith( - "# isort: split\n" - ): - if line == "# isort: off\n": - isort_off = True - if current: - if add_imports: - add_line_separator = line_separator or "\n" - current += add_line_separator + add_line_separator.join(add_imports) - add_imports = [] - parsed = parse.file_contents(current, config=config) - verbose_output += parsed.verbose_output - extra_space = "" - while current and current[-1] == "\n": - extra_space += "\n" - current = current[:-1] - extra_space = extra_space.replace("\n", "", 1) - sorted_output = output.sorted_imports( - parsed, config, extension, import_type="import" - ) - made_changes = made_changes or _has_changed( - before=current, - after=sorted_output, - line_separator=parsed.line_separator, - ignore_whitespace=config.ignore_whitespace, - ) - new_input += sorted_output - new_input += extra_space - current = "" - new_input += line or "" - else: - current += line or "" - - input_stream = StringIO(new_input) - - for index, line in enumerate(chain(input_stream, (None,))): - if line is None: - if index == 0 and not config.force_adds: - return False - - not_imports = True - end_of_file = True - line = "" - if not line_separator: - line_separator = "\n" - - if code_sorting and code_sorting_section: - output_stream.write( - textwrap.indent( - isort.literal.assignment( - code_sorting_section, - str(code_sorting), - extension, - config=_indented_config(config, indent), - ), - code_sorting_indent, - ) - ) - else: - stripped_line = line.strip() - if stripped_line and not line_separator: - line_separator = line[len(line.rstrip()) :].replace(" ", "").replace("\t", "") - - for file_skip_comment in FILE_SKIP_COMMENTS: - if file_skip_comment in line: - raise FileSkipComment("Passed in content") - - if not in_quote and stripped_line == "# isort: off": - isort_off = True - - if ( - (index == 0 or (index in (1, 2) and not contains_imports)) - and stripped_line.startswith("#") - and stripped_line not in config.section_comments - ): - in_top_comment = True - elif in_top_comment: - if not line.startswith("#") or stripped_line in config.section_comments: - in_top_comment = False - first_comment_index_end = index - 1 - - was_in_quote = bool(in_quote) - if (not stripped_line.startswith("#") or in_quote) and '"' in line or "'" in line: - char_index = 0 - if first_comment_index_start == -1 and ( - line.startswith('"') or line.startswith("'") - ): - first_comment_index_start = index - while char_index < len(line): - if line[char_index] == "\\": - char_index += 1 - elif in_quote: - if line[char_index : char_index + len(in_quote)] == in_quote: - in_quote = "" - if first_comment_index_end < first_comment_index_start: - first_comment_index_end = index - elif line[char_index] in ("'", '"'): - long_quote = line[char_index : char_index + 3] - if long_quote in ('"""', "'''"): - in_quote = long_quote - char_index += 2 - else: - in_quote = line[char_index] - elif line[char_index] == "#": - break - char_index += 1 - - not_imports = bool(in_quote) or was_in_quote or in_top_comment or isort_off - if not (in_quote or was_in_quote or in_top_comment): - if isort_off: - if stripped_line == "# isort: on": - isort_off = False - elif stripped_line.endswith("# isort: split"): - not_imports = True - elif stripped_line in CODE_SORT_COMMENTS: - code_sorting = stripped_line.split("isort: ")[1].strip() - code_sorting_indent = line[: -len(line.lstrip())] - not_imports = True - elif code_sorting: - if not stripped_line: - output_stream.write( - textwrap.indent( - isort.literal.assignment( - code_sorting_section, - str(code_sorting), - extension, - config=_indented_config(config, indent), - ), - code_sorting_indent, - ) - ) - not_imports = True - code_sorting = False - code_sorting_section = "" - code_sorting_indent = "" - else: - code_sorting_section += line - line = "" - elif stripped_line in config.section_comments: - if import_section and not contains_imports: - output_stream.write(import_section) - import_section = line - not_imports = False - else: - import_section += line - indent = line[: -len(line.lstrip())] - elif not (stripped_line or contains_imports): - not_imports = True - elif ( - not stripped_line - or stripped_line.startswith("#") - and (not indent or indent + line.lstrip() == line) - and not config.treat_all_comments_as_code - and stripped_line not in config.treat_comments_as_code - ): - import_section += line - elif stripped_line.startswith(IMPORT_START_IDENTIFIERS): - contains_imports = True - - new_indent = line[: -len(line.lstrip())] - import_statement = line - stripped_line = line.strip().split("#")[0] - while stripped_line.endswith("\\") or ( - "(" in stripped_line and ")" not in stripped_line - ): - if stripped_line.endswith("\\"): - while stripped_line and stripped_line.endswith("\\"): - line = input_stream.readline() - stripped_line = line.strip().split("#")[0] - import_statement += line - else: - while ")" not in stripped_line: - line = input_stream.readline() - stripped_line = line.strip().split("#")[0] - import_statement += line - - cimport_statement: bool = False - if ( - import_statement.lstrip().startswith(CIMPORT_IDENTIFIERS) - or " cimport " in import_statement - or " cimport*" in import_statement - or " cimport(" in import_statement - or ".cimport" in import_statement - ): - cimport_statement = True - - if cimport_statement != cimports or (new_indent != indent and import_section): - if import_section: - next_cimports = cimport_statement - next_import_section = import_statement - import_statement = "" - not_imports = True - line = "" - else: - cimports = cimport_statement - - indent = new_indent - import_section += import_statement - else: - not_imports = True - - if not_imports: - raw_import_section: str = import_section - if ( - add_imports - and (stripped_line or end_of_file) - and not config.append_only - and not in_top_comment - and not in_quote - and not import_section - and not line.lstrip().startswith(COMMENT_INDICATORS) - ): - import_section = line_separator.join(add_imports) + line_separator - if end_of_file and index != 0: - output_stream.write(line_separator) - contains_imports = True - add_imports = [] - - if next_import_section and not import_section: # pragma: no cover - raw_import_section = import_section = next_import_section - next_import_section = "" - - if import_section: - if add_imports and not indent: - import_section = ( - line_separator.join(add_imports) + line_separator + import_section - ) - contains_imports = True - add_imports = [] - - if not indent: - import_section += line - raw_import_section += line - if not contains_imports: - output_stream.write(import_section) - - else: - leading_whitespace = import_section[: -len(import_section.lstrip())] - trailing_whitespace = import_section[len(import_section.rstrip()) :] - if first_import_section and not import_section.lstrip( - line_separator - ).startswith(COMMENT_INDICATORS): - import_section = import_section.lstrip(line_separator) - raw_import_section = raw_import_section.lstrip(line_separator) - first_import_section = False - - if indent: - import_section = "".join( - line[len(indent) :] for line in import_section.splitlines(keepends=True) - ) - - parsed_content = parse.file_contents(import_section, config=config) - verbose_output += parsed_content.verbose_output - - sorted_import_section = output.sorted_imports( - parsed_content, - _indented_config(config, indent), - extension, - import_type="cimport" if cimports else "import", - ) - if not (import_section.strip() and not sorted_import_section): - if indent: - sorted_import_section = ( - leading_whitespace - + textwrap.indent(sorted_import_section, indent).strip() - + trailing_whitespace - ) - - made_changes = made_changes or _has_changed( - before=raw_import_section, - after=sorted_import_section, - line_separator=line_separator, - ignore_whitespace=config.ignore_whitespace, - ) - output_stream.write(sorted_import_section) - if not line and not indent and next_import_section: - output_stream.write(line_separator) - - if indent: - output_stream.write(line) - if not next_import_section: - indent = "" - - if next_import_section: - cimports = next_cimports - contains_imports = True - else: - contains_imports = False - import_section = next_import_section - next_import_section = "" - else: - output_stream.write(line) - not_imports = False - - if stripped_line and not in_quote and not import_section and not next_import_section: - if stripped_line == "yield": - while not stripped_line or stripped_line == "yield": - new_line = input_stream.readline() - if not new_line: - break - - output_stream.write(new_line) - stripped_line = new_line.strip().split("#")[0] - - if stripped_line.startswith("raise") or stripped_line.startswith("yield"): - while stripped_line.endswith("\\"): - new_line = input_stream.readline() - if not new_line: - break - - output_stream.write(new_line) - stripped_line = new_line.strip().split("#")[0] - - if made_changes and config.only_modified: - for output_str in verbose_output: - print(output_str) - - return made_changes - - -def _indented_config(config: Config, indent: str): - if not indent: - return config - - return Config( - config=config, - line_length=max(config.line_length - len(indent), 0), - wrap_length=max(config.wrap_length - len(indent), 0), - lines_after_imports=1, - ) - - -def _has_changed(before: str, after: str, line_separator: str, ignore_whitespace: bool) -> bool: - if ignore_whitespace: - return ( - remove_whitespace(before, line_separator=line_separator).strip() - != remove_whitespace(after, line_separator=line_separator).strip() - ) - else: - return before.strip() != after.strip() diff --git a/env/lib/python3.8/site-packages/isort/deprecated/__init__.py b/env/lib/python3.8/site-packages/isort/deprecated/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/env/lib/python3.8/site-packages/isort/deprecated/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/deprecated/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index abb0971728a5fad36bb94b9b69e4249e78f44a81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmYk0K?=e!5JgjPAwm!0qMe1CE<`+m8*v?C^JzlcBqV8}C-Dqk!(+Jh2<}{&tn|Zw z!+eI%T*`98lA7Ct=lRO`SCN)ua#$ruc4ph+bZ0)tKYV&pb_4~q9?=?5rz7`pHqc}= zInhRiQJ5;g&+r5@)1a^9mZ+@R)eQw5QKh?HbO@w_^^qi;M=K&Eajs3O-}iu LG~ke*cqg+jF|RfV diff --git a/env/lib/python3.8/site-packages/isort/deprecated/__pycache__/finders.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/deprecated/__pycache__/finders.cpython-38.pyc deleted file mode 100644 index 78a9175a09607e6c9fbe3a3db9a17a37d106602f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13551 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 i56 Iterator[None]: - """Context manager for changing dir and restoring previous workdir after exit.""" - curdir = os.getcwd() - os.chdir(path) - try: - yield - finally: - os.chdir(curdir) - - -class BaseFinder(metaclass=ABCMeta): - def __init__(self, config: Config) -> None: - self.config = config - - @abstractmethod - def find(self, module_name: str) -> Optional[str]: - raise NotImplementedError - - -class ForcedSeparateFinder(BaseFinder): - def find(self, module_name: str) -> Optional[str]: - for forced_separate in self.config.forced_separate: - # Ensure all forced_separate patterns will match to end of string - path_glob = forced_separate - if not forced_separate.endswith("*"): - path_glob = "%s*" % forced_separate - - if fnmatch(module_name, path_glob) or fnmatch(module_name, "." + path_glob): - return forced_separate - return None - - -class LocalFinder(BaseFinder): - def find(self, module_name: str) -> Optional[str]: - if module_name.startswith("."): - return "LOCALFOLDER" - return None - - -class KnownPatternFinder(BaseFinder): - def __init__(self, config: Config) -> None: - super().__init__(config) - - self.known_patterns: List[Tuple[Pattern[str], str]] = [] - for placement in reversed(config.sections): - known_placement = KNOWN_SECTION_MAPPING.get(placement, placement).lower() - config_key = f"known_{known_placement}" - known_patterns = list( - getattr(self.config, config_key, self.config.known_other.get(known_placement, [])) - ) - known_patterns = [ - pattern - for known_pattern in known_patterns - for pattern in self._parse_known_pattern(known_pattern) - ] - for known_pattern in known_patterns: - regexp = "^" + known_pattern.replace("*", ".*").replace("?", ".?") + "$" - self.known_patterns.append((re.compile(regexp), placement)) - - def _parse_known_pattern(self, pattern: str) -> List[str]: - """Expand pattern if identified as a directory and return found sub packages""" - if pattern.endswith(os.path.sep): - patterns = [ - filename - for filename in os.listdir(os.path.join(self.config.directory, pattern)) - if os.path.isdir(os.path.join(self.config.directory, pattern, filename)) - ] - else: - patterns = [pattern] - - return patterns - - def find(self, module_name: str) -> Optional[str]: - # Try to find most specific placement instruction match (if any) - parts = module_name.split(".") - module_names_to_check = (".".join(parts[:first_k]) for first_k in range(len(parts), 0, -1)) - for module_name_to_check in module_names_to_check: - for pattern, placement in self.known_patterns: - if pattern.match(module_name_to_check): - return placement - return None - - -class PathFinder(BaseFinder): - def __init__(self, config: Config, path: str = ".") -> None: - super().__init__(config) - - # restore the original import path (i.e. not the path to bin/isort) - root_dir = os.path.abspath(path) - src_dir = f"{root_dir}/src" - self.paths = [root_dir, src_dir] - - # virtual env - self.virtual_env = self.config.virtual_env or os.environ.get("VIRTUAL_ENV") - if self.virtual_env: - self.virtual_env = os.path.realpath(self.virtual_env) - self.virtual_env_src = "" - if self.virtual_env: - self.virtual_env_src = f"{self.virtual_env}/src/" - for venv_path in glob(f"{self.virtual_env}/lib/python*/site-packages"): - if venv_path not in self.paths: - self.paths.append(venv_path) - for nested_venv_path in glob(f"{self.virtual_env}/lib/python*/*/site-packages"): - if nested_venv_path not in self.paths: - self.paths.append(nested_venv_path) - for venv_src_path in glob(f"{self.virtual_env}/src/*"): - if os.path.isdir(venv_src_path): - self.paths.append(venv_src_path) - - # conda - self.conda_env = self.config.conda_env or os.environ.get("CONDA_PREFIX") or "" - if self.conda_env: - self.conda_env = os.path.realpath(self.conda_env) - for conda_path in glob(f"{self.conda_env}/lib/python*/site-packages"): - if conda_path not in self.paths: - self.paths.append(conda_path) - for nested_conda_path in glob(f"{self.conda_env}/lib/python*/*/site-packages"): - if nested_conda_path not in self.paths: - self.paths.append(nested_conda_path) - - # handle case-insensitive paths on windows - self.stdlib_lib_prefix = os.path.normcase(sysconfig.get_paths()["stdlib"]) - if self.stdlib_lib_prefix not in self.paths: - self.paths.append(self.stdlib_lib_prefix) - - # add system paths - for system_path in sys.path[1:]: - if system_path not in self.paths: - self.paths.append(system_path) - - def find(self, module_name: str) -> Optional[str]: - for prefix in self.paths: - package_path = "/".join((prefix, module_name.split(".")[0])) - path_obj = Path(package_path).resolve() - is_module = ( - exists_case_sensitive(package_path + ".py") - or any( - exists_case_sensitive(package_path + ext_suffix) - for ext_suffix in importlib.machinery.EXTENSION_SUFFIXES - ) - or exists_case_sensitive(package_path + "/__init__.py") - ) - is_package = exists_case_sensitive(package_path) and os.path.isdir(package_path) - if is_module or is_package: - if ( - "site-packages" in prefix - or "dist-packages" in prefix - or (self.virtual_env and self.virtual_env_src in prefix) - ): - return sections.THIRDPARTY - elif os.path.normcase(prefix) == self.stdlib_lib_prefix: - return sections.STDLIB - elif self.conda_env and self.conda_env in prefix: - return sections.THIRDPARTY - for src_path in self.config.src_paths: - if src_path in path_obj.parents and not self.config.is_skipped(path_obj): - return sections.FIRSTPARTY - - if os.path.normcase(prefix).startswith(self.stdlib_lib_prefix): - return sections.STDLIB # pragma: no cover - edge case for one OS. Hard to test. - - return self.config.default_section - return None - - -class ReqsBaseFinder(BaseFinder): - enabled = False - - def __init__(self, config: Config, path: str = ".") -> None: - super().__init__(config) - self.path = path - if self.enabled: - self.mapping = self._load_mapping() - self.names = self._load_names() - - @abstractmethod - def _get_names(self, path: str) -> Iterator[str]: - raise NotImplementedError - - @abstractmethod - def _get_files_from_dir(self, path: str) -> Iterator[str]: - raise NotImplementedError - - @staticmethod - def _load_mapping() -> Optional[Dict[str, str]]: - """Return list of mappings `package_name -> module_name` - - Example: - django-haystack -> haystack - """ - if not pipreqs: - return None - path = os.path.dirname(inspect.getfile(pipreqs)) - path = os.path.join(path, "mapping") - with open(path) as f: - mappings: Dict[str, str] = {} # pypi_name: import_name - for line in f: - import_name, _, pypi_name = line.strip().partition(":") - mappings[pypi_name] = import_name - return mappings - # return dict(tuple(line.strip().split(":")[::-1]) for line in f) - - def _load_names(self) -> List[str]: - """Return list of thirdparty modules from requirements""" - names = [] - for path in self._get_files(): - for name in self._get_names(path): - names.append(self._normalize_name(name)) - return names - - @staticmethod - def _get_parents(path: str) -> Iterator[str]: - prev = "" - while path != prev: - prev = path - yield path - path = os.path.dirname(path) - - def _get_files(self) -> Iterator[str]: - """Return paths to all requirements files""" - path = os.path.abspath(self.path) - if os.path.isfile(path): - path = os.path.dirname(path) - - for path in self._get_parents(path): - yield from self._get_files_from_dir(path) - - def _normalize_name(self, name: str) -> str: - """Convert package name to module name - - Examples: - Django -> django - django-haystack -> django_haystack - Flask-RESTFul -> flask_restful - """ - if self.mapping: - name = self.mapping.get(name.replace("-", "_"), name) - return name.lower().replace("-", "_") - - def find(self, module_name: str) -> Optional[str]: - # required lib not installed yet - if not self.enabled: - return None - - module_name, _sep, _submodules = module_name.partition(".") - module_name = module_name.lower() - if not module_name: - return None - - for name in self.names: - if module_name == name: - return sections.THIRDPARTY - return None - - -class RequirementsFinder(ReqsBaseFinder): - exts = (".txt", ".in") - enabled = bool(parse_requirements) - - def _get_files_from_dir(self, path: str) -> Iterator[str]: - """Return paths to requirements files from passed dir.""" - yield from self._get_files_from_dir_cached(path) - - @classmethod - @lru_cache(maxsize=16) - def _get_files_from_dir_cached(cls, path: str) -> List[str]: - results = [] - - for fname in os.listdir(path): - if "requirements" not in fname: - continue - full_path = os.path.join(path, fname) - - # *requirements*/*.{txt,in} - if os.path.isdir(full_path): - for subfile_name in os.listdir(full_path): - for ext in cls.exts: - if subfile_name.endswith(ext): - results.append(os.path.join(full_path, subfile_name)) - continue - - # *requirements*.{txt,in} - if os.path.isfile(full_path): - for ext in cls.exts: - if fname.endswith(ext): - results.append(full_path) - break - - return results - - def _get_names(self, path: str) -> Iterator[str]: - """Load required packages from path to requirements file""" - yield from self._get_names_cached(path) - - @classmethod - @lru_cache(maxsize=16) - def _get_names_cached(cls, path: str) -> List[str]: - result = [] - - with chdir(os.path.dirname(path)): - requirements = parse_requirements(path) - for req in requirements.values(): - if req.name: - result.append(req.name) - - return result - - -class PipfileFinder(ReqsBaseFinder): - enabled = bool(Pipfile) - - def _get_names(self, path: str) -> Iterator[str]: - with chdir(path): - project = Pipfile.load(path) - for req in project.packages: - yield req.name - - def _get_files_from_dir(self, path: str) -> Iterator[str]: - if "Pipfile" in os.listdir(path): - yield path - - -class DefaultFinder(BaseFinder): - def find(self, module_name: str) -> Optional[str]: - return self.config.default_section - - -class FindersManager: - _default_finders_classes: Sequence[Type[BaseFinder]] = ( - ForcedSeparateFinder, - LocalFinder, - KnownPatternFinder, - PathFinder, - PipfileFinder, - RequirementsFinder, - DefaultFinder, - ) - - def __init__( - self, config: Config, finder_classes: Optional[Iterable[Type[BaseFinder]]] = None - ) -> None: - self.verbose: bool = config.verbose - - if finder_classes is None: - finder_classes = self._default_finders_classes - finders: List[BaseFinder] = [] - for finder_cls in finder_classes: - try: - finders.append(finder_cls(config)) - except Exception as exception: - # if one finder fails to instantiate isort can continue using the rest - if self.verbose: - print( - ( - f"{finder_cls.__name__} encountered an error ({exception}) during " - "instantiation and cannot be used" - ) - ) - self.finders: Tuple[BaseFinder, ...] = tuple(finders) - - def find(self, module_name: str) -> Optional[str]: - for finder in self.finders: - try: - section = finder.find(module_name) - if section is not None: - return section - except Exception as exception: - # isort has to be able to keep trying to identify the correct - # import section even if one approach fails - if self.verbose: - print( - f"{finder.__class__.__name__} encountered an error ({exception}) while " - f"trying to identify the {module_name} module" - ) - return None diff --git a/env/lib/python3.8/site-packages/isort/exceptions.py b/env/lib/python3.8/site-packages/isort/exceptions.py deleted file mode 100644 index b98454a2..00000000 --- a/env/lib/python3.8/site-packages/isort/exceptions.py +++ /dev/null @@ -1,171 +0,0 @@ -"""All isort specific exception classes should be defined here""" -from pathlib import Path -from typing import Any, Dict, Union - -from .profiles import profiles - - -class ISortError(Exception): - """Base isort exception object from which all isort sourced exceptions should inherit""" - - -class InvalidSettingsPath(ISortError): - """Raised when a settings path is provided that is neither a valid file or directory""" - - def __init__(self, settings_path: str): - super().__init__( - f"isort was told to use the settings_path: {settings_path} as the base directory or " - "file that represents the starting point of config file discovery, but it does not " - "exist." - ) - self.settings_path = settings_path - - -class ExistingSyntaxErrors(ISortError): - """Raised when isort is told to sort imports within code that has existing syntax errors""" - - def __init__(self, file_path: str): - super().__init__( - f"isort was told to sort imports within code that contains syntax errors: " - f"{file_path}." - ) - self.file_path = file_path - - -class IntroducedSyntaxErrors(ISortError): - """Raised when isort has introduced a syntax error in the process of sorting imports""" - - def __init__(self, file_path: str): - super().__init__( - f"isort introduced syntax errors when attempting to sort the imports contained within " - f"{file_path}." - ) - self.file_path = file_path - - -class FileSkipped(ISortError): - """Should be raised when a file is skipped for any reason""" - - def __init__(self, message: str, file_path: str): - super().__init__(message) - self.file_path = file_path - - -class FileSkipComment(FileSkipped): - """Raised when an entire file is skipped due to a isort skip file comment""" - - def __init__(self, file_path: str): - super().__init__( - f"{file_path} contains an file skip comment and was skipped.", file_path=file_path - ) - - -class FileSkipSetting(FileSkipped): - """Raised when an entire file is skipped due to provided isort settings""" - - def __init__(self, file_path: str): - super().__init__( - f"{file_path} was skipped as it's listed in 'skip' setting" - " or matches a glob in 'skip_glob' setting", - file_path=file_path, - ) - - -class ProfileDoesNotExist(ISortError): - """Raised when a profile is set by the user that doesn't exist""" - - def __init__(self, profile: str): - super().__init__( - f"Specified profile of {profile} does not exist. " - f"Available profiles: {','.join(profiles)}." - ) - self.profile = profile - - -class FormattingPluginDoesNotExist(ISortError): - """Raised when a formatting plugin is set by the user that doesn't exist""" - - def __init__(self, formatter: str): - super().__init__(f"Specified formatting plugin of {formatter} does not exist. ") - self.formatter = formatter - - -class LiteralParsingFailure(ISortError): - """Raised when one of isorts literal sorting comments is used but isort can't parse the - the given data structure. - """ - - def __init__(self, code: str, original_error: Exception): - super().__init__( - f"isort failed to parse the given literal {code}. It's important to note " - "that isort literal sorting only supports simple literals parsable by " - f"ast.literal_eval which gave the exception of {original_error}." - ) - self.code = code - self.original_error = original_error - - -class LiteralSortTypeMismatch(ISortError): - """Raised when an isort literal sorting comment is used, with a type that doesn't match the - supplied data structure's type. - """ - - def __init__(self, kind: type, expected_kind: type): - super().__init__( - f"isort was told to sort a literal of type {expected_kind} but was given " - f"a literal of type {kind}." - ) - self.kind = kind - self.expected_kind = expected_kind - - -class AssignmentsFormatMismatch(ISortError): - """Raised when isort is told to sort assignments but the format of the assignment section - doesn't match isort's expectation. - """ - - def __init__(self, code: str): - super().__init__( - "isort was told to sort a section of assignments, however the given code:\n\n" - f"{code}\n\n" - "Does not match isort's strict single line formatting requirement for assignment " - "sorting:\n\n" - "{variable_name} = {value}\n" - "{variable_name2} = {value2}\n" - "...\n\n" - ) - self.code = code - - -class UnsupportedSettings(ISortError): - """Raised when settings are passed into isort (either from config, CLI, or runtime) - that it doesn't support. - """ - - @staticmethod - def _format_option(name: str, value: Any, source: str) -> str: - return f"\t- {name} = {value} (source: '{source}')" - - def __init__(self, unsupported_settings: Dict[str, Dict[str, str]]): - errors = "\n".join( - self._format_option(name, **option) for name, option in unsupported_settings.items() - ) - - super().__init__( - "isort was provided settings that it doesn't support:\n\n" - f"{errors}\n\n" - "For a complete and up-to-date listing of supported settings see: " - "https://pycqa.github.io/isort/docs/configuration/options/.\n" - ) - self.unsupported_settings = unsupported_settings - - -class UnsupportedEncoding(ISortError): - """Raised when isort encounters an encoding error while trying to read a file""" - - def __init__( - self, - filename: Union[str, Path], - ): - super().__init__(f"Unknown or unsupported encoding in {filename}") - self.filename = filename diff --git a/env/lib/python3.8/site-packages/isort/format.py b/env/lib/python3.8/site-packages/isort/format.py deleted file mode 100644 index 46bb1569..00000000 --- a/env/lib/python3.8/site-packages/isort/format.py +++ /dev/null @@ -1,149 +0,0 @@ -import re -import sys -from datetime import datetime -from difflib import unified_diff -from pathlib import Path -from typing import Optional, TextIO - -try: - import colorama -except ImportError: - colorama_unavailable = True -else: - colorama_unavailable = False - colorama.init() - - -ADDED_LINE_PATTERN = re.compile(r"\+[^+]") -REMOVED_LINE_PATTERN = re.compile(r"-[^-]") - - -def format_simplified(import_line: str) -> str: - import_line = import_line.strip() - if import_line.startswith("from "): - import_line = import_line.replace("from ", "") - import_line = import_line.replace(" import ", ".") - elif import_line.startswith("import "): - import_line = import_line.replace("import ", "") - - return import_line - - -def format_natural(import_line: str) -> str: - import_line = import_line.strip() - if not import_line.startswith("from ") and not import_line.startswith("import "): - if "." not in import_line: - return f"import {import_line}" - parts = import_line.split(".") - end = parts.pop(-1) - return f"from {'.'.join(parts)} import {end}" - - return import_line - - -def show_unified_diff( - *, - file_input: str, - file_output: str, - file_path: Optional[Path], - output: Optional[TextIO] = None, - color_output: bool = False, -): - """Shows a unified_diff for the provided input and output against the provided file path. - - - **file_input**: A string that represents the contents of a file before changes. - - **file_output**: A string that represents the contents of a file after changes. - - **file_path**: A Path object that represents the file path of the file being changed. - - **output**: A stream to output the diff to. If non is provided uses sys.stdout. - - **color_output**: Use color in output if True. - """ - printer = create_terminal_printer(color_output, output) - file_name = "" if file_path is None else str(file_path) - file_mtime = str( - datetime.now() if file_path is None else datetime.fromtimestamp(file_path.stat().st_mtime) - ) - unified_diff_lines = unified_diff( - file_input.splitlines(keepends=True), - file_output.splitlines(keepends=True), - fromfile=file_name + ":before", - tofile=file_name + ":after", - fromfiledate=file_mtime, - tofiledate=str(datetime.now()), - ) - for line in unified_diff_lines: - printer.diff_line(line) - - -def ask_whether_to_apply_changes_to_file(file_path: str) -> bool: - answer = None - while answer not in ("yes", "y", "no", "n", "quit", "q"): - answer = input(f"Apply suggested changes to '{file_path}' [y/n/q]? ") # nosec - answer = answer.lower() - if answer in ("no", "n"): - return False - if answer in ("quit", "q"): - sys.exit(1) - return True - - -def remove_whitespace(content: str, line_separator: str = "\n") -> str: - content = content.replace(line_separator, "").replace(" ", "").replace("\x0c", "") - return content - - -class BasicPrinter: - ERROR = "ERROR" - SUCCESS = "SUCCESS" - - def __init__(self, output: Optional[TextIO] = None): - self.output = output or sys.stdout - - def success(self, message: str) -> None: - print(f"{self.SUCCESS}: {message}", file=self.output) - - def error(self, message: str) -> None: - print(f"{self.ERROR}: {message}", file=sys.stderr) - - def diff_line(self, line: str) -> None: - self.output.write(line) - - -class ColoramaPrinter(BasicPrinter): - def __init__(self, output: Optional[TextIO] = None): - self.output = output or sys.stdout - # Note: this constants are instance variables instead ofs class variables - # because they refer to colorama which might not be installed. - self.ERROR = self.style_text("ERROR", colorama.Fore.RED) - self.SUCCESS = self.style_text("SUCCESS", colorama.Fore.GREEN) - self.ADDED_LINE = colorama.Fore.GREEN - self.REMOVED_LINE = colorama.Fore.RED - - @staticmethod - def style_text(text: str, style: Optional[str] = None) -> str: - if style is None: - return text - return style + text + colorama.Style.RESET_ALL - - def diff_line(self, line: str) -> None: - style = None - if re.match(ADDED_LINE_PATTERN, line): - style = self.ADDED_LINE - elif re.match(REMOVED_LINE_PATTERN, line): - style = self.REMOVED_LINE - self.output.write(self.style_text(line, style)) - - -def create_terminal_printer(color: bool, output: Optional[TextIO] = None): - if color and colorama_unavailable: - no_colorama_message = ( - "\n" - "Sorry, but to use --color (color_output) the colorama python package is required.\n\n" - "Reference: https://pypi.org/project/colorama/\n\n" - "You can either install it separately on your system or as the colors extra " - "for isort. Ex: \n\n" - "$ pip install isort[colors]\n" - ) - print(no_colorama_message, file=sys.stderr) - sys.exit(1) - - return ColoramaPrinter(output) if color else BasicPrinter(output) diff --git a/env/lib/python3.8/site-packages/isort/hooks.py b/env/lib/python3.8/site-packages/isort/hooks.py deleted file mode 100644 index acccede5..00000000 --- a/env/lib/python3.8/site-packages/isort/hooks.py +++ /dev/null @@ -1,90 +0,0 @@ -"""Defines a git hook to allow pre-commit warnings and errors about import order. - -usage: - exit_code = git_hook(strict=True|False, modify=True|False) -""" -import os -import subprocess # nosec - Needed for hook -from pathlib import Path -from typing import List - -from isort import Config, api, exceptions - - -def get_output(command: List[str]) -> str: - """ - Run a command and return raw output - - :param str command: the command to run - :returns: the stdout output of the command - """ - result = subprocess.run(command, stdout=subprocess.PIPE, check=True) # nosec - trusted input - return result.stdout.decode() - - -def get_lines(command: List[str]) -> List[str]: - """ - Run a command and return lines of output - - :param str command: the command to run - :returns: list of whitespace-stripped lines output by command - """ - stdout = get_output(command) - return [line.strip() for line in stdout.splitlines()] - - -def git_hook( - strict: bool = False, modify: bool = False, lazy: bool = False, settings_file: str = "" -) -> int: - """ - Git pre-commit hook to check staged files for isort errors - - :param bool strict - if True, return number of errors on exit, - causing the hook to fail. If False, return zero so it will - just act as a warning. - :param bool modify - if True, fix the sources if they are not - sorted properly. If False, only report result without - modifying anything. - :param bool lazy - if True, also check/fix unstaged files. - This is useful if you frequently use ``git commit -a`` for example. - If False, ony check/fix the staged files for isort errors. - :param str settings_file - A path to a file to be used as - the configuration file for this run. - When settings_file is the empty string, the configuration file - will be searched starting at the directory containing the first - staged file, if any, and going upward in the directory structure. - - :return number of errors if in strict mode, 0 otherwise. - """ - - # Get list of files modified and staged - diff_cmd = ["git", "diff-index", "--cached", "--name-only", "--diff-filter=ACMRTUXB", "HEAD"] - if lazy: - diff_cmd.remove("--cached") - - files_modified = get_lines(diff_cmd) - if not files_modified: - return 0 - - errors = 0 - config = Config( - settings_file=settings_file, - settings_path=os.path.dirname(os.path.abspath(files_modified[0])), - ) - for filename in files_modified: - if filename.endswith(".py"): - # Get the staged contents of the file - staged_cmd = ["git", "show", f":{filename}"] - staged_contents = get_output(staged_cmd) - - try: - if not api.check_code_string( - staged_contents, file_path=Path(filename), config=config - ): - errors += 1 - if modify: - api.sort_file(filename, config=config) - except exceptions.FileSkipped: # pragma: no cover - pass - - return errors if strict else 0 diff --git a/env/lib/python3.8/site-packages/isort/io.py b/env/lib/python3.8/site-packages/isort/io.py deleted file mode 100644 index 7ff2807d..00000000 --- a/env/lib/python3.8/site-packages/isort/io.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Defines any IO utilities used by isort""" -import re -import tokenize -from contextlib import contextmanager -from io import BytesIO, StringIO, TextIOWrapper -from pathlib import Path -from typing import Callable, Iterator, NamedTuple, TextIO, Union - -from isort.exceptions import UnsupportedEncoding - -_ENCODING_PATTERN = re.compile(br"^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)") - - -class File(NamedTuple): - stream: TextIO - path: Path - encoding: str - - @staticmethod - def detect_encoding(filename: str, readline: Callable[[], bytes]): - try: - return tokenize.detect_encoding(readline)[0] - except Exception: - raise UnsupportedEncoding(filename) - - @staticmethod - def from_contents(contents: str, filename: str) -> "File": - encoding = File.detect_encoding(filename, BytesIO(contents.encode("utf-8")).readline) - return File(StringIO(contents), path=Path(filename).resolve(), encoding=encoding) - - @property - def extension(self): - return self.path.suffix.lstrip(".") - - @staticmethod - def _open(filename): - """Open a file in read only mode using the encoding detected by - detect_encoding(). - """ - buffer = open(filename, "rb") - try: - encoding = File.detect_encoding(filename, buffer.readline) - buffer.seek(0) - text = TextIOWrapper(buffer, encoding, line_buffering=True, newline="") - text.mode = "r" # type: ignore - return text - except Exception: - buffer.close() - raise - - @staticmethod - @contextmanager - def read(filename: Union[str, Path]) -> Iterator["File"]: - file_path = Path(filename).resolve() - stream = None - try: - stream = File._open(file_path) - yield File(stream=stream, path=file_path, encoding=stream.encoding) - finally: - if stream is not None: - stream.close() - - -class _EmptyIO(StringIO): - def write(self, *args, **kwargs): - pass - - -Empty = _EmptyIO() diff --git a/env/lib/python3.8/site-packages/isort/literal.py b/env/lib/python3.8/site-packages/isort/literal.py deleted file mode 100644 index 01bd05e7..00000000 --- a/env/lib/python3.8/site-packages/isort/literal.py +++ /dev/null @@ -1,109 +0,0 @@ -import ast -from pprint import PrettyPrinter -from typing import Any, Callable, Dict, List, Set, Tuple - -from isort.exceptions import ( - AssignmentsFormatMismatch, - LiteralParsingFailure, - LiteralSortTypeMismatch, -) -from isort.settings import DEFAULT_CONFIG, Config - - -class ISortPrettyPrinter(PrettyPrinter): - """an isort customized pretty printer for sorted literals""" - - def __init__(self, config: Config): - super().__init__(width=config.line_length, compact=True) - - -type_mapping: Dict[str, Tuple[type, Callable[[Any, ISortPrettyPrinter], str]]] = {} - - -def assignments(code: str) -> str: - values = {} - for line in code.splitlines(keepends=True): - if not line.strip(): - continue - if " = " not in line: - raise AssignmentsFormatMismatch(code) - variable_name, value = line.split(" = ", 1) - values[variable_name] = value - - return "".join( - f"{variable_name} = {values[variable_name]}" for variable_name in sorted(values.keys()) - ) - - -def assignment(code: str, sort_type: str, extension: str, config: Config = DEFAULT_CONFIG) -> str: - """Sorts the literal present within the provided code against the provided sort type, - returning the sorted representation of the source code. - """ - if sort_type == "assignments": - return assignments(code) - elif sort_type not in type_mapping: - raise ValueError( - "Trying to sort using an undefined sort_type. " - f"Defined sort types are {', '.join(type_mapping.keys())}." - ) - - variable_name, literal = code.split(" = ") - variable_name = variable_name.lstrip() - try: - value = ast.literal_eval(literal) - except Exception as error: - raise LiteralParsingFailure(code, error) - - expected_type, sort_function = type_mapping[sort_type] - if type(value) != expected_type: - raise LiteralSortTypeMismatch(type(value), expected_type) - - printer = ISortPrettyPrinter(config) - sorted_value_code = f"{variable_name} = {sort_function(value, printer)}" - if config.formatting_function: - sorted_value_code = config.formatting_function( - sorted_value_code, extension, config - ).rstrip() - - sorted_value_code += code[len(code.rstrip()) :] - return sorted_value_code - - -def register_type(name: str, kind: type): - """Registers a new literal sort type.""" - - def wrap(function): - type_mapping[name] = (kind, function) - return function - - return wrap - - -@register_type("dict", dict) -def _dict(value: Dict[Any, Any], printer: ISortPrettyPrinter) -> str: - return printer.pformat(dict(sorted(value.items(), key=lambda item: item[1]))) - - -@register_type("list", list) -def _list(value: List[Any], printer: ISortPrettyPrinter) -> str: - return printer.pformat(sorted(value)) - - -@register_type("unique-list", list) -def _unique_list(value: List[Any], printer: ISortPrettyPrinter) -> str: - return printer.pformat(list(sorted(set(value)))) - - -@register_type("set", set) -def _set(value: Set[Any], printer: ISortPrettyPrinter) -> str: - return "{" + printer.pformat(tuple(sorted(value)))[1:-1] + "}" - - -@register_type("tuple", tuple) -def _tuple(value: Tuple[Any, ...], printer: ISortPrettyPrinter) -> str: - return printer.pformat(tuple(sorted(value))) - - -@register_type("unique-tuple", tuple) -def _unique_tuple(value: Tuple[Any, ...], printer: ISortPrettyPrinter) -> str: - return printer.pformat(tuple(sorted(set(value)))) diff --git a/env/lib/python3.8/site-packages/isort/logo.py b/env/lib/python3.8/site-packages/isort/logo.py deleted file mode 100644 index 6377d868..00000000 --- a/env/lib/python3.8/site-packages/isort/logo.py +++ /dev/null @@ -1,19 +0,0 @@ -from ._version import __version__ - -ASCII_ART = rf""" - _ _ - (_) ___ ___ _ __| |_ - | |/ _/ / _ \/ '__ _/ - | |\__ \/\_\/| | | |_ - |_|\___/\___/\_/ \_/ - - isort your imports, so you don't have to. - - VERSION {__version__} -""" - -__doc__ = f""" -```python -{ASCII_ART} -``` -""" diff --git a/env/lib/python3.8/site-packages/isort/main.py b/env/lib/python3.8/site-packages/isort/main.py deleted file mode 100644 index a8e59f0e..00000000 --- a/env/lib/python3.8/site-packages/isort/main.py +++ /dev/null @@ -1,1022 +0,0 @@ -"""Tool for sorting imports alphabetically, and automatically separated into sections.""" -import argparse -import functools -import json -import os -import sys -from io import TextIOWrapper -from pathlib import Path -from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence, Set -from warnings import warn - -from . import __version__, api, sections -from .exceptions import FileSkipped, UnsupportedEncoding -from .format import create_terminal_printer -from .logo import ASCII_ART -from .profiles import profiles -from .settings import VALID_PY_TARGETS, Config, WrapModes - -try: - from .setuptools_commands import ISortCommand # noqa: F401 -except ImportError: - pass - -DEPRECATED_SINGLE_DASH_ARGS = { - "-ac", - "-af", - "-ca", - "-cs", - "-df", - "-ds", - "-dt", - "-fas", - "-fass", - "-ff", - "-fgw", - "-fss", - "-lai", - "-lbt", - "-le", - "-ls", - "-nis", - "-nlb", - "-ot", - "-rr", - "-sd", - "-sg", - "-sl", - "-sp", - "-tc", - "-wl", - "-ws", -} -QUICK_GUIDE = f""" -{ASCII_ART} - -Nothing to do: no files or paths have have been passed in! - -Try one of the following: - - `isort .` - sort all Python files, starting from the current directory, recursively. - `isort . --interactive` - Do the same, but ask before making any changes. - `isort . --check --diff` - Check to see if imports are correctly sorted within this project. - `isort --help` - In-depth information about isort's available command-line options. - -Visit https://pycqa.github.io/isort/ for complete information about how to use isort. -""" - - -class SortAttempt: - def __init__(self, incorrectly_sorted: bool, skipped: bool, supported_encoding: bool) -> None: - self.incorrectly_sorted = incorrectly_sorted - self.skipped = skipped - self.supported_encoding = supported_encoding - - -def sort_imports( - file_name: str, - config: Config, - check: bool = False, - ask_to_apply: bool = False, - write_to_stdout: bool = False, - **kwargs: Any, -) -> Optional[SortAttempt]: - try: - incorrectly_sorted: bool = False - skipped: bool = False - if check: - try: - incorrectly_sorted = not api.check_file(file_name, config=config, **kwargs) - except FileSkipped: - skipped = True - return SortAttempt(incorrectly_sorted, skipped, True) - else: - try: - incorrectly_sorted = not api.sort_file( - file_name, - config=config, - ask_to_apply=ask_to_apply, - write_to_stdout=write_to_stdout, - **kwargs, - ) - except FileSkipped: - skipped = True - return SortAttempt(incorrectly_sorted, skipped, True) - except (OSError, ValueError) as error: - warn(f"Unable to parse file {file_name} due to {error}") - return None - except UnsupportedEncoding: - if config.verbose: - warn(f"Encoding not supported for {file_name}") - return SortAttempt(incorrectly_sorted, skipped, False) - except Exception: - printer = create_terminal_printer(color=config.color_output) - printer.error( - f"Unrecoverable exception thrown when parsing {file_name}! " - "This should NEVER happen.\n" - "If encountered, please open an issue: https://github.com/PyCQA/isort/issues/new" - ) - raise - - -def iter_source_code( - paths: Iterable[str], config: Config, skipped: List[str], broken: List[str] -) -> Iterator[str]: - """Iterate over all Python source files defined in paths.""" - visited_dirs: Set[Path] = set() - - for path in paths: - if os.path.isdir(path): - for dirpath, dirnames, filenames in os.walk(path, topdown=True, followlinks=True): - base_path = Path(dirpath) - for dirname in list(dirnames): - full_path = base_path / dirname - resolved_path = full_path.resolve() - if config.is_skipped(full_path): - skipped.append(dirname) - dirnames.remove(dirname) - else: - if resolved_path in visited_dirs: # pragma: no cover - if not config.quiet: - warn(f"Likely recursive symlink detected to {resolved_path}") - dirnames.remove(dirname) - visited_dirs.add(resolved_path) - - for filename in filenames: - filepath = os.path.join(dirpath, filename) - if config.is_supported_filetype(filepath): - if config.is_skipped(Path(filepath)): - skipped.append(filename) - else: - yield filepath - elif not os.path.exists(path): - broken.append(path) - else: - yield path - - -def _build_arg_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser( - description="Sort Python import definitions alphabetically " - "within logical sections. Run with no arguments to see a quick " - "start guide, otherwise, one or more files/directories/stdin must be provided. " - "Use `-` as the first argument to represent stdin. Use --interactive to use the pre 5.0.0 " - "interactive behavior." - " " - "If you've used isort 4 but are new to isort 5, see the upgrading guide:" - "https://pycqa.github.io/isort/docs/upgrade_guides/5.0.0/." - ) - inline_args_group = parser.add_mutually_exclusive_group() - parser.add_argument( - "--src", - "--src-path", - dest="src_paths", - action="append", - help="Add an explicitly defined source path " - "(modules within src paths have their imports automatically categorized as first_party).", - ) - parser.add_argument( - "-a", - "--add-import", - dest="add_imports", - action="append", - help="Adds the specified import line to all files, " - "automatically determining correct placement.", - ) - parser.add_argument( - "--append", - "--append-only", - dest="append_only", - action="store_true", - help="Only adds the imports specified in --add-imports if the file" - " contains existing imports.", - ) - parser.add_argument( - "--ac", - "--atomic", - dest="atomic", - action="store_true", - help="Ensures the output doesn't save if the resulting file contains syntax errors.", - ) - parser.add_argument( - "--af", - "--force-adds", - dest="force_adds", - action="store_true", - help="Forces import adds even if the original file is empty.", - ) - parser.add_argument( - "-b", - "--builtin", - dest="known_standard_library", - action="append", - help="Force isort to recognize a module as part of Python's standard library.", - ) - parser.add_argument( - "--extra-builtin", - dest="extra_standard_library", - action="append", - help="Extra modules to be included in the list of ones in Python's standard library.", - ) - parser.add_argument( - "-c", - "--check-only", - "--check", - action="store_true", - dest="check", - help="Checks the file for unsorted / unformatted imports and prints them to the " - "command line without modifying the file.", - ) - parser.add_argument( - "--ca", - "--combine-as", - dest="combine_as_imports", - action="store_true", - help="Combines as imports on the same line.", - ) - parser.add_argument( - "--cs", - "--combine-star", - dest="combine_star", - action="store_true", - help="Ensures that if a star import is present, " - "nothing else is imported from that namespace.", - ) - parser.add_argument( - "-d", - "--stdout", - help="Force resulting output to stdout, instead of in-place.", - dest="write_to_stdout", - action="store_true", - ) - parser.add_argument( - "--df", - "--diff", - dest="show_diff", - action="store_true", - help="Prints a diff of all the changes isort would make to a file, instead of " - "changing it in place", - ) - parser.add_argument( - "--ds", - "--no-sections", - help="Put all imports into the same section bucket", - dest="no_sections", - action="store_true", - ) - parser.add_argument( - "-e", - "--balanced", - dest="balanced_wrapping", - action="store_true", - help="Balances wrapping to produce the most consistent line length possible", - ) - parser.add_argument( - "-f", - "--future", - dest="known_future_library", - action="append", - help="Force isort to recognize a module as part of Python's internal future compatibility " - "libraries. WARNING: this overrides the behavior of __future__ handling and therefore" - " can result in code that can't execute. If you're looking to add dependencies such " - "as six a better option is to create a another section below --future using custom " - "sections. See: https://github.com/PyCQA/isort#custom-sections-and-ordering and the " - "discussion here: https://github.com/PyCQA/isort/issues/1463.", - ) - parser.add_argument( - "--fas", - "--force-alphabetical-sort", - action="store_true", - dest="force_alphabetical_sort", - help="Force all imports to be sorted as a single section", - ) - parser.add_argument( - "--fass", - "--force-alphabetical-sort-within-sections", - action="store_true", - dest="force_alphabetical_sort_within_sections", - help="Force all imports to be sorted alphabetically within a section", - ) - parser.add_argument( - "--ff", - "--from-first", - dest="from_first", - help="Switches the typical ordering preference, " - "showing from imports first then straight ones.", - ) - parser.add_argument( - "--fgw", - "--force-grid-wrap", - nargs="?", - const=2, - type=int, - dest="force_grid_wrap", - help="Force number of from imports (defaults to 2 when passed as CLI flag without value)" - "to be grid wrapped regardless of line " - "length. If 0 is passed in (the global default) only line length is considered.", - ) - parser.add_argument( - "--fss", - "--force-sort-within-sections", - action="store_true", - dest="force_sort_within_sections", - help="Don't sort straight-style imports (like import sys) before from-style imports " - "(like from itertools import groupby). Instead, sort the imports by module, " - "independent of import style.", - ) - parser.add_argument( - "-i", - "--indent", - help='String to place for indents defaults to " " (4 spaces).', - dest="indent", - type=str, - ) - parser.add_argument( - "-j", "--jobs", help="Number of files to process in parallel.", dest="jobs", type=int - ) - parser.add_argument("--lai", "--lines-after-imports", dest="lines_after_imports", type=int) - parser.add_argument("--lbt", "--lines-between-types", dest="lines_between_types", type=int) - parser.add_argument( - "--le", - "--line-ending", - dest="line_ending", - help="Forces line endings to the specified value. " - "If not set, values will be guessed per-file.", - ) - parser.add_argument( - "--ls", - "--length-sort", - help="Sort imports by their string length.", - dest="length_sort", - action="store_true", - ) - parser.add_argument( - "--lss", - "--length-sort-straight", - help="Sort straight imports by their string length. Similar to `length_sort` " - "but applies only to straight imports and doesn't affect from imports.", - dest="length_sort_straight", - action="store_true", - ) - parser.add_argument( - "-m", - "--multi-line", - dest="multi_line_output", - choices=list(WrapModes.__members__.keys()) - + [str(mode.value) for mode in WrapModes.__members__.values()], - type=str, - help="Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, " - "5-vert-grid-grouped, 6-vert-grid-grouped-no-comma, 7-noqa, " - "8-vertical-hanging-indent-bracket, 9-vertical-prefix-from-module-import, " - "10-hanging-indent-with-parentheses).", - ) - parser.add_argument( - "-n", - "--ensure-newline-before-comments", - dest="ensure_newline_before_comments", - action="store_true", - help="Inserts a blank line before a comment following an import.", - ) - inline_args_group.add_argument( - "--nis", - "--no-inline-sort", - dest="no_inline_sort", - action="store_true", - help="Leaves `from` imports with multiple imports 'as-is' " - "(e.g. `from foo import a, c ,b`).", - ) - parser.add_argument( - "--nlb", - "--no-lines-before", - help="Sections which should not be split with previous by empty lines", - dest="no_lines_before", - action="append", - ) - parser.add_argument( - "-o", - "--thirdparty", - dest="known_third_party", - action="append", - help="Force isort to recognize a module as being part of a third party library.", - ) - parser.add_argument( - "--ot", - "--order-by-type", - dest="order_by_type", - action="store_true", - help="Order imports by type, which is determined by case, in addition to alphabetically.\n" - "\n**NOTE**: type here refers to the implied type from the import name capitalization.\n" - ' isort does not do type introspection for the imports. These "types" are simply: ' - "CONSTANT_VARIABLE, CamelCaseClass, variable_or_function. If your project follows PEP8" - " or a related coding standard and has many imports this is a good default, otherwise you " - "likely will want to turn it off. From the CLI the `--dont-order-by-type` option will turn " - "this off.", - ) - parser.add_argument( - "--dt", - "--dont-order-by-type", - dest="dont_order_by_type", - action="store_true", - help="Don't order imports by type, which is determined by case, in addition to " - "alphabetically.\n\n" - "**NOTE**: type here refers to the implied type from the import name capitalization.\n" - ' isort does not do type introspection for the imports. These "types" are simply: ' - "CONSTANT_VARIABLE, CamelCaseClass, variable_or_function. If your project follows PEP8" - " or a related coding standard and has many imports this is a good default. You can turn " - "this on from the CLI using `--order-by-type`.", - ) - parser.add_argument( - "-p", - "--project", - dest="known_first_party", - action="append", - help="Force isort to recognize a module as being part of the current python project.", - ) - parser.add_argument( - "--known-local-folder", - dest="known_local_folder", - action="append", - help="Force isort to recognize a module as being a local folder. " - "Generally, this is reserved for relative imports (from . import module).", - ) - parser.add_argument( - "-q", - "--quiet", - action="store_true", - dest="quiet", - help="Shows extra quiet output, only errors are outputted.", - ) - parser.add_argument( - "--rm", - "--remove-import", - dest="remove_imports", - action="append", - help="Removes the specified import from all files.", - ) - parser.add_argument( - "--rr", - "--reverse-relative", - dest="reverse_relative", - action="store_true", - help="Reverse order of relative imports.", - ) - parser.add_argument( - "-s", - "--skip", - help="Files that sort imports should skip over. If you want to skip multiple " - "files you should specify twice: --skip file1 --skip file2.", - dest="skip", - action="append", - ) - parser.add_argument( - "--sd", - "--section-default", - dest="default_section", - help="Sets the default section for import options: " + str(sections.DEFAULT), - ) - parser.add_argument( - "--sg", - "--skip-glob", - help="Files that sort imports should skip over.", - dest="skip_glob", - action="append", - ) - parser.add_argument( - "--gitignore", - "--skip-gitignore", - action="store_true", - dest="skip_gitignore", - help="Treat project as a git repository and ignore files listed in .gitignore", - ) - inline_args_group.add_argument( - "--sl", - "--force-single-line-imports", - dest="force_single_line", - action="store_true", - help="Forces all from imports to appear on their own line", - ) - parser.add_argument( - "--nsl", - "--single-line-exclusions", - help="One or more modules to exclude from the single line rule.", - dest="single_line_exclusions", - action="append", - ) - parser.add_argument( - "--sp", - "--settings-path", - "--settings-file", - "--settings", - dest="settings_path", - help="Explicitly set the settings path or file instead of auto determining " - "based on file location.", - ) - parser.add_argument( - "-t", - "--top", - help="Force specific imports to the top of their appropriate section.", - dest="force_to_top", - action="append", - ) - parser.add_argument( - "--tc", - "--trailing-comma", - dest="include_trailing_comma", - action="store_true", - help="Includes a trailing comma on multi line imports that include parentheses.", - ) - parser.add_argument( - "--up", - "--use-parentheses", - dest="use_parentheses", - action="store_true", - help="Use parentheses for line continuation on length limit instead of slashes." - " **NOTE**: This is separate from wrap modes, and only affects how individual lines that " - " are too long get continued, not sections of multiple imports.", - ) - parser.add_argument( - "-V", - "--version", - action="store_true", - dest="show_version", - help="Displays the currently installed version of isort.", - ) - parser.add_argument( - "-v", - "--verbose", - action="store_true", - dest="verbose", - help="Shows verbose output, such as when files are skipped or when a check is successful.", - ) - parser.add_argument( - "--virtual-env", - dest="virtual_env", - help="Virtual environment to use for determining whether a package is third-party", - ) - parser.add_argument( - "--conda-env", - dest="conda_env", - help="Conda environment to use for determining whether a package is third-party", - ) - parser.add_argument( - "--vn", - "--version-number", - action="version", - version=__version__, - help="Returns just the current version number without the logo", - ) - parser.add_argument( - "-l", - "-w", - "--line-length", - "--line-width", - help="The max length of an import line (used for wrapping long imports).", - dest="line_length", - type=int, - ) - parser.add_argument( - "--wl", - "--wrap-length", - dest="wrap_length", - type=int, - help="Specifies how long lines that are wrapped should be, if not set line_length is used." - "\nNOTE: wrap_length must be LOWER than or equal to line_length.", - ) - parser.add_argument( - "--ws", - "--ignore-whitespace", - action="store_true", - dest="ignore_whitespace", - help="Tells isort to ignore whitespace differences when --check-only is being used.", - ) - parser.add_argument( - "--case-sensitive", - dest="case_sensitive", - action="store_true", - help="Tells isort to include casing when sorting module names", - ) - parser.add_argument( - "--filter-files", - dest="filter_files", - action="store_true", - help="Tells isort to filter files even when they are explicitly passed in as " - "part of the CLI command.", - ) - parser.add_argument( - "files", nargs="*", help="One or more Python source files that need their imports sorted." - ) - parser.add_argument( - "--py", - "--python-version", - action="store", - dest="py_version", - choices=tuple(VALID_PY_TARGETS) + ("auto",), - help="Tells isort to set the known standard library based on the specified Python " - "version. Default is to assume any Python 3 version could be the target, and use a union " - "of all stdlib modules across versions. If auto is specified, the version of the " - "interpreter used to run isort " - f"(currently: {sys.version_info.major}{sys.version_info.minor}) will be used.", - ) - parser.add_argument( - "--profile", - dest="profile", - type=str, - help="Base profile type to use for configuration. " - f"Profiles include: {', '.join(profiles.keys())}. As well as any shared profiles.", - ) - parser.add_argument( - "--interactive", - dest="ask_to_apply", - action="store_true", - help="Tells isort to apply changes interactively.", - ) - parser.add_argument( - "--old-finders", - "--magic-placement", - dest="old_finders", - action="store_true", - help="Use the old deprecated finder logic that relies on environment introspection magic.", - ) - parser.add_argument( - "--show-config", - dest="show_config", - action="store_true", - help="See isort's determined config, as well as sources of config options.", - ) - parser.add_argument( - "--show-files", - dest="show_files", - action="store_true", - help="See the files isort will be ran against with the current config options.", - ) - parser.add_argument( - "--honor-noqa", - dest="honor_noqa", - action="store_true", - help="Tells isort to honor noqa comments to enforce skipping those comments.", - ) - parser.add_argument( - "--remove-redundant-aliases", - dest="remove_redundant_aliases", - action="store_true", - help=( - "Tells isort to remove redundant aliases from imports, such as `import os as os`." - " This defaults to `False` simply because some projects use these seemingly useless " - " aliases to signify intent and change behaviour." - ), - ) - parser.add_argument( - "--color", - dest="color_output", - action="store_true", - help="Tells isort to use color in terminal output.", - ) - parser.add_argument( - "--float-to-top", - dest="float_to_top", - action="store_true", - help="Causes all non-indented imports to float to the top of the file having its imports " - "sorted (immediately below the top of file comment).\n" - "This can be an excellent shortcut for collecting imports every once in a while " - "when you place them in the middle of a file to avoid context switching.\n\n" - "*NOTE*: It currently doesn't work with cimports and introduces some extra over-head " - "and a performance penalty.", - ) - parser.add_argument( - "--treat-comment-as-code", - dest="treat_comments_as_code", - action="append", - help="Tells isort to treat the specified single line comment(s) as if they are code.", - ) - parser.add_argument( - "--treat-all-comment-as-code", - dest="treat_all_comments_as_code", - action="store_true", - help="Tells isort to treat all single line comments as if they are code.", - ) - parser.add_argument( - "--formatter", - dest="formatter", - type=str, - help="Specifies the name of a formatting plugin to use when producing output.", - ) - parser.add_argument( - "--ext", - "--extension", - "--supported-extension", - dest="supported_extensions", - action="append", - help="Specifies what extensions isort can be ran against.", - ) - parser.add_argument( - "--blocked-extension", - dest="blocked_extensions", - action="append", - help="Specifies what extensions isort can never be ran against.", - ) - parser.add_argument( - "--dedup-headings", - dest="dedup_headings", - action="store_true", - help="Tells isort to only show an identical custom import heading comment once, even if" - " there are multiple sections with the comment set.", - ) - - # deprecated options - parser.add_argument( - "--recursive", - dest="deprecated_flags", - action="append_const", - const="--recursive", - help=argparse.SUPPRESS, - ) - parser.add_argument( - "-rc", dest="deprecated_flags", action="append_const", const="-rc", help=argparse.SUPPRESS - ) - parser.add_argument( - "--dont-skip", - dest="deprecated_flags", - action="append_const", - const="--dont-skip", - help=argparse.SUPPRESS, - ) - parser.add_argument( - "-ns", dest="deprecated_flags", action="append_const", const="-ns", help=argparse.SUPPRESS - ) - parser.add_argument( - "--apply", - dest="deprecated_flags", - action="append_const", - const="--apply", - help=argparse.SUPPRESS, - ) - parser.add_argument( - "-k", - "--keep-direct-and-as", - dest="deprecated_flags", - action="append_const", - const="--keep-direct-and-as", - help=argparse.SUPPRESS, - ) - - parser.add_argument( - "--only-sections", - "--os", - dest="only_sections", - action="store_true", - help="Causes imports to be sorted only based on their sections like STDLIB,THIRDPARTY etc. " - "Imports are unaltered and keep their relative positions within the different sections.", - ) - - parser.add_argument( - "--only-modified", - "--om", - dest="only_modified", - action="store_true", - help="Suppresses verbose output for non-modified files.", - ) - - return parser - - -def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]: - argv = sys.argv[1:] if argv is None else list(argv) - remapped_deprecated_args = [] - for index, arg in enumerate(argv): - if arg in DEPRECATED_SINGLE_DASH_ARGS: - remapped_deprecated_args.append(arg) - argv[index] = f"-{arg}" - - parser = _build_arg_parser() - arguments = {key: value for key, value in vars(parser.parse_args(argv)).items() if value} - if remapped_deprecated_args: - arguments["remapped_deprecated_args"] = remapped_deprecated_args - if "dont_order_by_type" in arguments: - arguments["order_by_type"] = False - del arguments["dont_order_by_type"] - multi_line_output = arguments.get("multi_line_output", None) - if multi_line_output: - if multi_line_output.isdigit(): - arguments["multi_line_output"] = WrapModes(int(multi_line_output)) - else: - arguments["multi_line_output"] = WrapModes[multi_line_output] - return arguments - - -def _preconvert(item): - """Preconverts objects from native types into JSONifyiable types""" - if isinstance(item, (set, frozenset)): - return list(item) - elif isinstance(item, WrapModes): - return item.name - elif isinstance(item, Path): - return str(item) - elif callable(item) and hasattr(item, "__name__"): - return item.__name__ - else: - raise TypeError("Unserializable object {} of type {}".format(item, type(item))) - - -def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = None) -> None: - arguments = parse_args(argv) - if arguments.get("show_version"): - print(ASCII_ART) - return - - show_config: bool = arguments.pop("show_config", False) - show_files: bool = arguments.pop("show_files", False) - if show_config and show_files: - sys.exit("Error: either specify show-config or show-files not both.") - - if "settings_path" in arguments: - if os.path.isfile(arguments["settings_path"]): - arguments["settings_file"] = os.path.abspath(arguments["settings_path"]) - arguments["settings_path"] = os.path.dirname(arguments["settings_file"]) - else: - arguments["settings_path"] = os.path.abspath(arguments["settings_path"]) - - if "virtual_env" in arguments: - venv = arguments["virtual_env"] - arguments["virtual_env"] = os.path.abspath(venv) - if not os.path.isdir(arguments["virtual_env"]): - warn(f"virtual_env dir does not exist: {arguments['virtual_env']}") - - file_names = arguments.pop("files", []) - if not file_names and not show_config: - print(QUICK_GUIDE) - if arguments: - sys.exit("Error: arguments passed in without any paths or content.") - else: - return - if "settings_path" not in arguments: - arguments["settings_path"] = ( - os.path.abspath(file_names[0] if file_names else ".") or os.getcwd() - ) - if not os.path.isdir(arguments["settings_path"]): - arguments["settings_path"] = os.path.dirname(arguments["settings_path"]) - - config_dict = arguments.copy() - ask_to_apply = config_dict.pop("ask_to_apply", False) - jobs = config_dict.pop("jobs", ()) - check = config_dict.pop("check", False) - show_diff = config_dict.pop("show_diff", False) - write_to_stdout = config_dict.pop("write_to_stdout", False) - deprecated_flags = config_dict.pop("deprecated_flags", False) - remapped_deprecated_args = config_dict.pop("remapped_deprecated_args", False) - wrong_sorted_files = False - all_attempt_broken = False - no_valid_encodings = False - - if "src_paths" in config_dict: - config_dict["src_paths"] = { - Path(src_path).resolve() for src_path in config_dict.get("src_paths", ()) - } - - config = Config(**config_dict) - if show_config: - print(json.dumps(config.__dict__, indent=4, separators=(",", ": "), default=_preconvert)) - return - elif file_names == ["-"]: - if show_files: - sys.exit("Error: can't show files for streaming input.") - - if check: - incorrectly_sorted = not api.check_stream( - input_stream=sys.stdin if stdin is None else stdin, - config=config, - show_diff=show_diff, - ) - - wrong_sorted_files = incorrectly_sorted - else: - api.sort_stream( - input_stream=sys.stdin if stdin is None else stdin, - output_stream=sys.stdout, - config=config, - show_diff=show_diff, - ) - else: - skipped: List[str] = [] - broken: List[str] = [] - - if config.filter_files: - filtered_files = [] - for file_name in file_names: - if config.is_skipped(Path(file_name)): - skipped.append(file_name) - else: - filtered_files.append(file_name) - file_names = filtered_files - - file_names = iter_source_code(file_names, config, skipped, broken) - if show_files: - for file_name in file_names: - print(file_name) - return - num_skipped = 0 - num_broken = 0 - num_invalid_encoding = 0 - if config.verbose: - print(ASCII_ART) - - if jobs: - import multiprocessing - - executor = multiprocessing.Pool(jobs) - attempt_iterator = executor.imap( - functools.partial( - sort_imports, - config=config, - check=check, - ask_to_apply=ask_to_apply, - write_to_stdout=write_to_stdout, - ), - file_names, - ) - else: - # https://github.com/python/typeshed/pull/2814 - attempt_iterator = ( - sort_imports( # type: ignore - file_name, - config=config, - check=check, - ask_to_apply=ask_to_apply, - show_diff=show_diff, - write_to_stdout=write_to_stdout, - ) - for file_name in file_names - ) - - # If any files passed in are missing considered as error, should be removed - is_no_attempt = True - any_encoding_valid = False - for sort_attempt in attempt_iterator: - if not sort_attempt: - continue # pragma: no cover - shouldn't happen, satisfies type constraint - incorrectly_sorted = sort_attempt.incorrectly_sorted - if arguments.get("check", False) and incorrectly_sorted: - wrong_sorted_files = True - if sort_attempt.skipped: - num_skipped += ( - 1 # pragma: no cover - shouldn't happen, due to skip in iter_source_code - ) - - if not sort_attempt.supported_encoding: - num_invalid_encoding += 1 - else: - any_encoding_valid = True - - is_no_attempt = False - - num_skipped += len(skipped) - if num_skipped and not arguments.get("quiet", False): - if config.verbose: - for was_skipped in skipped: - warn( - f"{was_skipped} was skipped as it's listed in 'skip' setting" - " or matches a glob in 'skip_glob' setting" - ) - print(f"Skipped {num_skipped} files") - - num_broken += len(broken) - if num_broken and not arguments.get("quite", False): - if config.verbose: - for was_broken in broken: - warn(f"{was_broken} was broken path, make sure it exists correctly") - print(f"Broken {num_broken} paths") - - if num_broken > 0 and is_no_attempt: - all_attempt_broken = True - if num_invalid_encoding > 0 and not any_encoding_valid: - no_valid_encodings = True - - if not config.quiet and (remapped_deprecated_args or deprecated_flags): - if remapped_deprecated_args: - warn( - "W0502: The following deprecated single dash CLI flags were used and translated: " - f"{', '.join(remapped_deprecated_args)}!" - ) - if deprecated_flags: - warn( - "W0501: The following deprecated CLI flags were used and ignored: " - f"{', '.join(deprecated_flags)}!" - ) - warn( - "W0500: Please see the 5.0.0 Upgrade guide: " - "https://pycqa.github.io/isort/docs/upgrade_guides/5.0.0/" - ) - - if wrong_sorted_files: - sys.exit(1) - - if all_attempt_broken: - sys.exit(1) - - if no_valid_encodings: - printer = create_terminal_printer(color=config.color_output) - printer.error("No valid encodings.") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/env/lib/python3.8/site-packages/isort/output.py b/env/lib/python3.8/site-packages/isort/output.py deleted file mode 100644 index d2633ffd..00000000 --- a/env/lib/python3.8/site-packages/isort/output.py +++ /dev/null @@ -1,584 +0,0 @@ -import copy -import itertools -from functools import partial -from typing import Iterable, List, Set, Tuple - -from isort.format import format_simplified - -from . import parse, sorting, wrap -from .comments import add_to_line as with_comments -from .settings import DEFAULT_CONFIG, Config - -STATEMENT_DECLARATIONS: Tuple[str, ...] = ("def ", "cdef ", "cpdef ", "class ", "@", "async def") - - -def sorted_imports( - parsed: parse.ParsedContent, - config: Config = DEFAULT_CONFIG, - extension: str = "py", - import_type: str = "import", -) -> str: - """Adds the imports back to the file. - - (at the index of the first import) sorted alphabetically and split between groups - - """ - if parsed.import_index == -1: - return _output_as_string(parsed.lines_without_imports, parsed.line_separator) - - formatted_output: List[str] = parsed.lines_without_imports.copy() - remove_imports = [format_simplified(removal) for removal in config.remove_imports] - - sections: Iterable[str] = itertools.chain(parsed.sections, config.forced_separate) - - if config.no_sections: - parsed.imports["no_sections"] = {"straight": {}, "from": {}} - base_sections: Tuple[str, ...] = () - for section in sections: - if section == "FUTURE": - base_sections = ("FUTURE",) - continue - parsed.imports["no_sections"]["straight"].update( - parsed.imports[section].get("straight", {}) - ) - parsed.imports["no_sections"]["from"].update(parsed.imports[section].get("from", {})) - sections = base_sections + ("no_sections",) - - output: List[str] = [] - seen_headings: Set[str] = set() - pending_lines_before = False - for section in sections: - straight_modules = parsed.imports[section]["straight"] - if not config.only_sections: - straight_modules = sorting.naturally( - straight_modules, - key=lambda key: sorting.module_key( - key, config, section_name=section, straight_import=True - ), - ) - - from_modules = parsed.imports[section]["from"] - if not config.only_sections: - from_modules = sorting.naturally( - from_modules, key=lambda key: sorting.module_key(key, config, section_name=section) - ) - - straight_imports = _with_straight_imports( - parsed, config, straight_modules, section, remove_imports, import_type - ) - from_imports = _with_from_imports( - parsed, config, from_modules, section, remove_imports, import_type - ) - - lines_between = [""] * ( - config.lines_between_types if from_modules and straight_modules else 0 - ) - if config.from_first: - section_output = from_imports + lines_between + straight_imports - else: - section_output = straight_imports + lines_between + from_imports - - if config.force_sort_within_sections: - # collapse comments - comments_above = [] - new_section_output: List[str] = [] - for line in section_output: - if not line: - continue - if line.startswith("#"): - comments_above.append(line) - elif comments_above: - new_section_output.append(_LineWithComments(line, comments_above)) - comments_above = [] - else: - new_section_output.append(line) - # only_sections options is not imposed if force_sort_within_sections is True - new_section_output = sorting.naturally( - new_section_output, - key=partial( - sorting.section_key, - order_by_type=config.order_by_type, - force_to_top=config.force_to_top, - lexicographical=config.lexicographical, - length_sort=config.length_sort, - reverse_relative=config.reverse_relative, - group_by_package=config.group_by_package, - ), - ) - - # uncollapse comments - section_output = [] - for line in new_section_output: - comments = getattr(line, "comments", ()) - if comments: - section_output.extend(comments) - section_output.append(str(line)) - - section_name = section - no_lines_before = section_name in config.no_lines_before - - if section_output: - if section_name in parsed.place_imports: - parsed.place_imports[section_name] = section_output - continue - - section_title = config.import_headings.get(section_name.lower(), "") - if section_title and section_title not in seen_headings: - if config.dedup_headings: - seen_headings.add(section_title) - section_comment = f"# {section_title}" - if section_comment not in parsed.lines_without_imports[0:1]: - section_output.insert(0, section_comment) - - if pending_lines_before or not no_lines_before: - output += [""] * config.lines_between_sections - - output += section_output - - pending_lines_before = False - else: - pending_lines_before = pending_lines_before or not no_lines_before - - if config.ensure_newline_before_comments: - output = _ensure_newline_before_comment(output) - - while output and output[-1].strip() == "": - output.pop() # pragma: no cover - while output and output[0].strip() == "": - output.pop(0) - - if config.formatting_function: - output = config.formatting_function( - parsed.line_separator.join(output), extension, config - ).splitlines() - - output_at = 0 - if parsed.import_index < parsed.original_line_count: - output_at = parsed.import_index - formatted_output[output_at:0] = output - - imports_tail = output_at + len(output) - while [ - character.strip() for character in formatted_output[imports_tail : imports_tail + 1] - ] == [""]: - formatted_output.pop(imports_tail) - - if len(formatted_output) > imports_tail: - next_construct = "" - tail = formatted_output[imports_tail:] - - for index, line in enumerate(tail): - should_skip, in_quote, *_ = parse.skip_line( - line, - in_quote="", - index=len(formatted_output), - section_comments=config.section_comments, - needs_import=False, - ) - if not should_skip and line.strip(): - if ( - line.strip().startswith("#") - and len(tail) > (index + 1) - and tail[index + 1].strip() - ): - continue - next_construct = line - break - elif in_quote: - next_construct = line - break - - if config.lines_after_imports != -1: - formatted_output[imports_tail:0] = ["" for line in range(config.lines_after_imports)] - elif extension != "pyi" and next_construct.startswith(STATEMENT_DECLARATIONS): - formatted_output[imports_tail:0] = ["", ""] - else: - formatted_output[imports_tail:0] = [""] - - if parsed.place_imports: - new_out_lines = [] - for index, line in enumerate(formatted_output): - new_out_lines.append(line) - if line in parsed.import_placements: - new_out_lines.extend(parsed.place_imports[parsed.import_placements[line]]) - if ( - len(formatted_output) <= (index + 1) - or formatted_output[index + 1].strip() != "" - ): - new_out_lines.append("") - formatted_output = new_out_lines - - return _output_as_string(formatted_output, parsed.line_separator) - - -def _with_from_imports( - parsed: parse.ParsedContent, - config: Config, - from_modules: Iterable[str], - section: str, - remove_imports: List[str], - import_type: str, -) -> List[str]: - output: List[str] = [] - for module in from_modules: - if module in remove_imports: - continue - - import_start = f"from {module} {import_type} " - from_imports = list(parsed.imports[section]["from"][module]) - if not config.no_inline_sort or ( - config.force_single_line and module not in config.single_line_exclusions - ): - ignore_case = config.force_alphabetical_sort_within_sections - - if not config.only_sections: - from_imports = sorting.naturally( - from_imports, - key=lambda key: sorting.module_key( - key, - config, - True, - ignore_case, - section_name=section, - ), - ) - if remove_imports: - from_imports = [ - line for line in from_imports if f"{module}.{line}" not in remove_imports - ] - - sub_modules = [f"{module}.{from_import}" for from_import in from_imports] - as_imports = { - from_import: [ - f"{from_import} as {as_module}" for as_module in parsed.as_map["from"][sub_module] - ] - for from_import, sub_module in zip(from_imports, sub_modules) - if sub_module in parsed.as_map["from"] - } - if config.combine_as_imports and not ("*" in from_imports and config.combine_star): - if not config.no_inline_sort: - for as_import in as_imports: - if not config.only_sections: - as_imports[as_import] = sorting.naturally(as_imports[as_import]) - for from_import in copy.copy(from_imports): - if from_import in as_imports: - idx = from_imports.index(from_import) - if parsed.imports[section]["from"][module][from_import]: - from_imports[(idx + 1) : (idx + 1)] = as_imports.pop(from_import) - else: - from_imports[idx : (idx + 1)] = as_imports.pop(from_import) - - only_show_as_imports = False - comments = parsed.categorized_comments["from"].pop(module, ()) - above_comments = parsed.categorized_comments["above"]["from"].pop(module, None) - while from_imports: - if above_comments: - output.extend(above_comments) - above_comments = None - - if "*" in from_imports and config.combine_star: - import_statement = wrap.line( - with_comments( - _with_star_comments(parsed, module, list(comments or ())), - f"{import_start}*", - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ), - parsed.line_separator, - config, - ) - from_imports = [ - from_import for from_import in from_imports if from_import in as_imports - ] - only_show_as_imports = True - elif config.force_single_line and module not in config.single_line_exclusions: - import_statement = "" - while from_imports: - from_import = from_imports.pop(0) - single_import_line = with_comments( - comments, - import_start + from_import, - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - comment = ( - parsed.categorized_comments["nested"].get(module, {}).pop(from_import, None) - ) - if comment: - single_import_line += ( - f"{comments and ';' or config.comment_prefix} " f"{comment}" - ) - if from_import in as_imports: - if ( - parsed.imports[section]["from"][module][from_import] - and not only_show_as_imports - ): - output.append( - wrap.line(single_import_line, parsed.line_separator, config) - ) - from_comments = parsed.categorized_comments["straight"].get( - f"{module}.{from_import}" - ) - - if not config.only_sections: - output.extend( - with_comments( - from_comments, - wrap.line( - import_start + as_import, parsed.line_separator, config - ), - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - for as_import in sorting.naturally(as_imports[from_import]) - ) - - else: - output.extend( - with_comments( - from_comments, - wrap.line( - import_start + as_import, parsed.line_separator, config - ), - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - for as_import in as_imports[from_import] - ) - else: - output.append(wrap.line(single_import_line, parsed.line_separator, config)) - comments = None - else: - while from_imports and from_imports[0] in as_imports: - from_import = from_imports.pop(0) - - if not config.only_sections: - as_imports[from_import] = sorting.naturally(as_imports[from_import]) - from_comments = ( - parsed.categorized_comments["straight"].get(f"{module}.{from_import}") or [] - ) - if ( - parsed.imports[section]["from"][module][from_import] - and not only_show_as_imports - ): - specific_comment = ( - parsed.categorized_comments["nested"] - .get(module, {}) - .pop(from_import, None) - ) - if specific_comment: - from_comments.append(specific_comment) - output.append( - wrap.line( - with_comments( - from_comments, - import_start + from_import, - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ), - parsed.line_separator, - config, - ) - ) - from_comments = [] - - for as_import in as_imports[from_import]: - specific_comment = ( - parsed.categorized_comments["nested"] - .get(module, {}) - .pop(as_import, None) - ) - if specific_comment: - from_comments.append(specific_comment) - - output.append( - wrap.line( - with_comments( - from_comments, - import_start + as_import, - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ), - parsed.line_separator, - config, - ) - ) - - from_comments = [] - - if "*" in from_imports: - output.append( - with_comments( - _with_star_comments(parsed, module, list(comments or ())), - f"{import_start}*", - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - ) - from_imports.remove("*") - comments = None - - for from_import in copy.copy(from_imports): - comment = ( - parsed.categorized_comments["nested"].get(module, {}).pop(from_import, None) - ) - if comment: - single_import_line = with_comments( - comments, - import_start + from_import, - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - single_import_line += ( - f"{comments and ';' or config.comment_prefix} " f"{comment}" - ) - output.append(wrap.line(single_import_line, parsed.line_separator, config)) - from_imports.remove(from_import) - comments = None - - from_import_section = [] - while from_imports and ( - from_imports[0] not in as_imports - or ( - config.combine_as_imports - and parsed.imports[section]["from"][module][from_import] - ) - ): - from_import_section.append(from_imports.pop(0)) - if config.combine_as_imports: - comments = (comments or []) + list( - parsed.categorized_comments["from"].pop(f"{module}.__combined_as__", ()) - ) - import_statement = with_comments( - comments, - import_start + (", ").join(from_import_section), - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - if not from_import_section: - import_statement = "" - - do_multiline_reformat = False - - force_grid_wrap = config.force_grid_wrap - if force_grid_wrap and len(from_import_section) >= force_grid_wrap: - do_multiline_reformat = True - - if len(import_statement) > config.line_length and len(from_import_section) > 1: - do_multiline_reformat = True - - # If line too long AND have imports AND we are - # NOT using GRID or VERTICAL wrap modes - if ( - len(import_statement) > config.line_length - and len(from_import_section) > 0 - and config.multi_line_output - not in (wrap.Modes.GRID, wrap.Modes.VERTICAL) # type: ignore - ): - do_multiline_reformat = True - - if do_multiline_reformat: - import_statement = wrap.import_statement( - import_start=import_start, - from_imports=from_import_section, - comments=comments, - line_separator=parsed.line_separator, - config=config, - ) - if config.multi_line_output == wrap.Modes.GRID: # type: ignore - other_import_statement = wrap.import_statement( - import_start=import_start, - from_imports=from_import_section, - comments=comments, - line_separator=parsed.line_separator, - config=config, - multi_line_output=wrap.Modes.VERTICAL_GRID, # type: ignore - ) - if max(len(x) for x in import_statement.split("\n")) > config.line_length: - import_statement = other_import_statement - if not do_multiline_reformat and len(import_statement) > config.line_length: - import_statement = wrap.line(import_statement, parsed.line_separator, config) - - if import_statement: - output.append(import_statement) - return output - - -def _with_straight_imports( - parsed: parse.ParsedContent, - config: Config, - straight_modules: Iterable[str], - section: str, - remove_imports: List[str], - import_type: str, -) -> List[str]: - output: List[str] = [] - for module in straight_modules: - if module in remove_imports: - continue - - import_definition = [] - if module in parsed.as_map["straight"]: - if parsed.imports[section]["straight"][module]: - import_definition.append(f"{import_type} {module}") - import_definition.extend( - f"{import_type} {module} as {as_import}" - for as_import in parsed.as_map["straight"][module] - ) - else: - import_definition.append(f"{import_type} {module}") - - comments_above = parsed.categorized_comments["above"]["straight"].pop(module, None) - if comments_above: - output.extend(comments_above) - output.extend( - with_comments( - parsed.categorized_comments["straight"].get(module), - idef, - removed=config.ignore_comments, - comment_prefix=config.comment_prefix, - ) - for idef in import_definition - ) - - return output - - -def _output_as_string(lines: List[str], line_separator: str) -> str: - return line_separator.join(_normalize_empty_lines(lines)) - - -def _normalize_empty_lines(lines: List[str]) -> List[str]: - while lines and lines[-1].strip() == "": - lines.pop(-1) - - lines.append("") - return lines - - -class _LineWithComments(str): - def __new__(cls, value, comments): - instance = super().__new__(cls, value) # type: ignore - instance.comments = comments - return instance - - -def _ensure_newline_before_comment(output): - new_output: List[str] = [] - - def is_comment(line): - return line and line.startswith("#") - - for line, prev_line in zip(output, [None] + output): - if is_comment(line) and prev_line != "" and not is_comment(prev_line): - new_output.append("") - new_output.append(line) - return new_output - - -def _with_star_comments(parsed: parse.ParsedContent, module: str, comments: List[str]) -> List[str]: - star_comment = parsed.categorized_comments["nested"].get(module, {}).pop("*", None) - if star_comment: - return comments + [star_comment] - else: - return comments diff --git a/env/lib/python3.8/site-packages/isort/parse.py b/env/lib/python3.8/site-packages/isort/parse.py deleted file mode 100644 index fe3dd157..00000000 --- a/env/lib/python3.8/site-packages/isort/parse.py +++ /dev/null @@ -1,548 +0,0 @@ -"""Defines parsing functions used by isort for parsing import definitions""" -from collections import OrderedDict, defaultdict -from functools import partial -from itertools import chain -from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional, Tuple -from warnings import warn - -from . import place -from .comments import parse as parse_comments -from .deprecated.finders import FindersManager -from .settings import DEFAULT_CONFIG, Config - -if TYPE_CHECKING: - from mypy_extensions import TypedDict - - CommentsAboveDict = TypedDict( - "CommentsAboveDict", {"straight": Dict[str, Any], "from": Dict[str, Any]} - ) - - CommentsDict = TypedDict( - "CommentsDict", - { - "from": Dict[str, Any], - "straight": Dict[str, Any], - "nested": Dict[str, Any], - "above": CommentsAboveDict, - }, - ) - - -def _infer_line_separator(contents: str) -> str: - if "\r\n" in contents: - return "\r\n" - elif "\r" in contents: - return "\r" - else: - return "\n" - - -def _normalize_line(raw_line: str) -> Tuple[str, str]: - """Normalizes import related statements in the provided line. - - Returns (normalized_line: str, raw_line: str) - """ - line = raw_line.replace("from.import ", "from . import ") - line = line.replace("from.cimport ", "from . cimport ") - line = line.replace("import*", "import *") - line = line.replace(" .import ", " . import ") - line = line.replace(" .cimport ", " . cimport ") - line = line.replace("\t", " ") - return (line, raw_line) - - -def import_type(line: str, config: Config = DEFAULT_CONFIG) -> Optional[str]: - """If the current line is an import line it will return its type (from or straight)""" - if config.honor_noqa and line.lower().rstrip().endswith("noqa"): - return None - elif "isort:skip" in line or "isort: skip" in line or "isort: split" in line: - return None - elif line.startswith(("import ", "cimport ")): - return "straight" - elif line.startswith("from "): - return "from" - return None - - -def _strip_syntax(import_string: str) -> str: - import_string = import_string.replace("_import", "[[i]]") - import_string = import_string.replace("_cimport", "[[ci]]") - for remove_syntax in ["\\", "(", ")", ","]: - import_string = import_string.replace(remove_syntax, " ") - import_list = import_string.split() - for key in ("from", "import", "cimport"): - if key in import_list: - import_list.remove(key) - import_string = " ".join(import_list) - import_string = import_string.replace("[[i]]", "_import") - import_string = import_string.replace("[[ci]]", "_cimport") - return import_string.replace("{ ", "{|").replace(" }", "|}") - - -def skip_line( - line: str, - in_quote: str, - index: int, - section_comments: Tuple[str, ...], - needs_import: bool = True, -) -> Tuple[bool, str]: - """Determine if a given line should be skipped. - - Returns back a tuple containing: - - (skip_line: bool, - in_quote: str,) - """ - should_skip = bool(in_quote) - if '"' in line or "'" in line: - char_index = 0 - while char_index < len(line): - if line[char_index] == "\\": - char_index += 1 - elif in_quote: - if line[char_index : char_index + len(in_quote)] == in_quote: - in_quote = "" - elif line[char_index] in ("'", '"'): - long_quote = line[char_index : char_index + 3] - if long_quote in ('"""', "'''"): - in_quote = long_quote - char_index += 2 - else: - in_quote = line[char_index] - elif line[char_index] == "#": - break - char_index += 1 - - if ";" in line.split("#")[0] and needs_import: - for part in (part.strip() for part in line.split(";")): - if ( - part - and not part.startswith("from ") - and not part.startswith(("import ", "cimport ")) - ): - should_skip = True - - return (bool(should_skip or in_quote), in_quote) - - -class ParsedContent(NamedTuple): - in_lines: List[str] - lines_without_imports: List[str] - import_index: int - place_imports: Dict[str, List[str]] - import_placements: Dict[str, str] - as_map: Dict[str, Dict[str, List[str]]] - imports: Dict[str, Dict[str, Any]] - categorized_comments: "CommentsDict" - change_count: int - original_line_count: int - line_separator: str - sections: Any - verbose_output: List[str] - - -def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedContent: - """Parses a python file taking out and categorizing imports.""" - line_separator: str = config.line_ending or _infer_line_separator(contents) - in_lines = contents.splitlines() - if contents and contents[-1] in ("\n", "\r"): - in_lines.append("") - - out_lines = [] - original_line_count = len(in_lines) - if config.old_finders: - finder = FindersManager(config=config).find - else: - finder = partial(place.module, config=config) - - line_count = len(in_lines) - - place_imports: Dict[str, List[str]] = {} - import_placements: Dict[str, str] = {} - as_map: Dict[str, Dict[str, List[str]]] = { - "straight": defaultdict(list), - "from": defaultdict(list), - } - imports: OrderedDict[str, Dict[str, Any]] = OrderedDict() - verbose_output: List[str] = [] - - for section in chain(config.sections, config.forced_separate): - imports[section] = {"straight": OrderedDict(), "from": OrderedDict()} - categorized_comments: CommentsDict = { - "from": {}, - "straight": {}, - "nested": {}, - "above": {"straight": {}, "from": {}}, - } - - index = 0 - import_index = -1 - in_quote = "" - while index < line_count: - line = in_lines[index] - index += 1 - statement_index = index - (skipping_line, in_quote) = skip_line( - line, in_quote=in_quote, index=index, section_comments=config.section_comments - ) - - if line in config.section_comments and not skipping_line: - if import_index == -1: - import_index = index - 1 - continue - - if "isort:imports-" in line and line.startswith("#"): - section = line.split("isort:imports-")[-1].split()[0].upper() - place_imports[section] = [] - import_placements[line] = section - elif "isort: imports-" in line and line.startswith("#"): - section = line.split("isort: imports-")[-1].split()[0].upper() - place_imports[section] = [] - import_placements[line] = section - - if skipping_line: - out_lines.append(line) - continue - - lstripped_line = line.lstrip() - if ( - config.float_to_top - and import_index == -1 - and line - and not in_quote - and not lstripped_line.startswith("#") - and not lstripped_line.startswith("'''") - and not lstripped_line.startswith('"""') - ): - if not lstripped_line.startswith("import") and not lstripped_line.startswith("from"): - import_index = index - 1 - while import_index and not in_lines[import_index - 1]: - import_index -= 1 - else: - commentless = line.split("#", 1)[0].strip() - if ( - ("isort:skip" in line or "isort: skip" in line) - and "(" in commentless - and ")" not in commentless - ): - import_index = index - - starting_line = line - while "isort:skip" in starting_line or "isort: skip" in starting_line: - commentless = starting_line.split("#", 1)[0] - if ( - "(" in commentless - and not commentless.rstrip().endswith(")") - and import_index < line_count - ): - - while import_index < line_count and not commentless.rstrip().endswith( - ")" - ): - commentless = in_lines[import_index].split("#", 1)[0] - import_index += 1 - else: - import_index += 1 - - if import_index >= line_count: - break - else: - starting_line = in_lines[import_index] - - line, *end_of_line_comment = line.split("#", 1) - if ";" in line: - statements = [line.strip() for line in line.split(";")] - else: - statements = [line] - if end_of_line_comment: - statements[-1] = f"{statements[-1]}#{end_of_line_comment[0]}" - - for statement in statements: - line, raw_line = _normalize_line(statement) - type_of_import = import_type(line, config) or "" - if not type_of_import: - out_lines.append(raw_line) - continue - - if import_index == -1: - import_index = index - 1 - nested_comments = {} - import_string, comment = parse_comments(line) - comments = [comment] if comment else [] - line_parts = [part for part in _strip_syntax(import_string).strip().split(" ") if part] - if type_of_import == "from" and len(line_parts) == 2 and comments: - nested_comments[line_parts[-1]] = comments[0] - - if "(" in line.split("#", 1)[0] and index < line_count: - while not line.split("#")[0].strip().endswith(")") and index < line_count: - line, new_comment = parse_comments(in_lines[index]) - index += 1 - if new_comment: - comments.append(new_comment) - stripped_line = _strip_syntax(line).strip() - if ( - type_of_import == "from" - and stripped_line - and " " not in stripped_line.replace(" as ", "") - and new_comment - ): - nested_comments[stripped_line] = comments[-1] - import_string += line_separator + line - else: - while line.strip().endswith("\\"): - line, new_comment = parse_comments(in_lines[index]) - index += 1 - if new_comment: - comments.append(new_comment) - - # Still need to check for parentheses after an escaped line - if ( - "(" in line.split("#")[0] - and ")" not in line.split("#")[0] - and index < line_count - ): - stripped_line = _strip_syntax(line).strip() - if ( - type_of_import == "from" - and stripped_line - and " " not in stripped_line.replace(" as ", "") - and new_comment - ): - nested_comments[stripped_line] = comments[-1] - import_string += line_separator + line - - while not line.split("#")[0].strip().endswith(")") and index < line_count: - line, new_comment = parse_comments(in_lines[index]) - index += 1 - if new_comment: - comments.append(new_comment) - stripped_line = _strip_syntax(line).strip() - if ( - type_of_import == "from" - and stripped_line - and " " not in stripped_line.replace(" as ", "") - and new_comment - ): - nested_comments[stripped_line] = comments[-1] - import_string += line_separator + line - - stripped_line = _strip_syntax(line).strip() - if ( - type_of_import == "from" - and stripped_line - and " " not in stripped_line.replace(" as ", "") - and new_comment - ): - nested_comments[stripped_line] = comments[-1] - if import_string.strip().endswith( - (" import", " cimport") - ) or line.strip().startswith(("import ", "cimport ")): - import_string += line_separator + line - else: - import_string = import_string.rstrip().rstrip("\\") + " " + line.lstrip() - - if type_of_import == "from": - cimports: bool - import_string = ( - import_string.replace("import(", "import (") - .replace("\\", " ") - .replace("\n", " ") - ) - if " cimport " in import_string: - parts = import_string.split(" cimport ") - cimports = True - - else: - parts = import_string.split(" import ") - cimports = False - - from_import = parts[0].split(" ") - import_string = (" cimport " if cimports else " import ").join( - [from_import[0] + " " + "".join(from_import[1:])] + parts[1:] - ) - - just_imports = [ - item.replace("{|", "{ ").replace("|}", " }") - for item in _strip_syntax(import_string).split() - ] - - attach_comments_to: Optional[List[Any]] = None - direct_imports = just_imports[1:] - straight_import = True - if "as" in just_imports and (just_imports.index("as") + 1) < len(just_imports): - straight_import = False - while "as" in just_imports: - nested_module = None - as_index = just_imports.index("as") - if type_of_import == "from": - nested_module = just_imports[as_index - 1] - top_level_module = just_imports[0] - module = top_level_module + "." + nested_module - as_name = just_imports[as_index + 1] - direct_imports.remove(nested_module) - direct_imports.remove(as_name) - direct_imports.remove("as") - if nested_module == as_name and config.remove_redundant_aliases: - pass - elif as_name not in as_map["from"][module]: - as_map["from"][module].append(as_name) - - full_name = f"{nested_module} as {as_name}" - associated_comment = nested_comments.get(full_name) - if associated_comment: - categorized_comments["nested"].setdefault(top_level_module, {})[ - full_name - ] = associated_comment - if associated_comment in comments: - comments.pop(comments.index(associated_comment)) - else: - module = just_imports[as_index - 1] - as_name = just_imports[as_index + 1] - if module == as_name and config.remove_redundant_aliases: - pass - elif as_name not in as_map["straight"][module]: - as_map["straight"][module].append(as_name) - - if comments and attach_comments_to is None: - if nested_module and config.combine_as_imports: - attach_comments_to = categorized_comments["from"].setdefault( - f"{top_level_module}.__combined_as__", [] - ) - else: - attach_comments_to = categorized_comments["straight"].setdefault( - module, [] - ) - del just_imports[as_index : as_index + 2] - - if type_of_import == "from": - import_from = just_imports.pop(0) - placed_module = finder(import_from) - if config.verbose and not config.only_modified: - print(f"from-type place_module for {import_from} returned {placed_module}") - - elif config.verbose: - verbose_output.append( - f"from-type place_module for {import_from} returned {placed_module}" - ) - if placed_module == "": - warn( - f"could not place module {import_from} of line {line} --" - " Do you need to define a default section?" - ) - root = imports[placed_module][type_of_import] # type: ignore - for import_name in just_imports: - associated_comment = nested_comments.get(import_name) - if associated_comment: - categorized_comments["nested"].setdefault(import_from, {})[ - import_name - ] = associated_comment - if associated_comment in comments: - comments.pop(comments.index(associated_comment)) - - if comments and attach_comments_to is None: - attach_comments_to = categorized_comments["from"].setdefault(import_from, []) - - if len(out_lines) > max(import_index, 1) - 1: - last = out_lines and out_lines[-1].rstrip() or "" - while ( - last.startswith("#") - and not last.endswith('"""') - and not last.endswith("'''") - and "isort:imports-" not in last - and "isort: imports-" not in last - and not config.treat_all_comments_as_code - and not last.strip() in config.treat_comments_as_code - ): - categorized_comments["above"]["from"].setdefault(import_from, []).insert( - 0, out_lines.pop(-1) - ) - if out_lines: - last = out_lines[-1].rstrip() - else: - last = "" - if statement_index - 1 == import_index: # pragma: no cover - import_index -= len( - categorized_comments["above"]["from"].get(import_from, []) - ) - - if import_from not in root: - root[import_from] = OrderedDict( - (module, module in direct_imports) for module in just_imports - ) - else: - root[import_from].update( - (module, root[import_from].get(module, False) or module in direct_imports) - for module in just_imports - ) - - if comments and attach_comments_to is not None: - attach_comments_to.extend(comments) - else: - if comments and attach_comments_to is not None: - attach_comments_to.extend(comments) - comments = [] - - for module in just_imports: - if comments: - categorized_comments["straight"][module] = comments - comments = [] - - if len(out_lines) > max(import_index, +1, 1) - 1: - - last = out_lines and out_lines[-1].rstrip() or "" - while ( - last.startswith("#") - and not last.endswith('"""') - and not last.endswith("'''") - and "isort:imports-" not in last - and "isort: imports-" not in last - and not config.treat_all_comments_as_code - and not last.strip() in config.treat_comments_as_code - ): - categorized_comments["above"]["straight"].setdefault(module, []).insert( - 0, out_lines.pop(-1) - ) - if out_lines: - last = out_lines[-1].rstrip() - else: - last = "" - if index - 1 == import_index: - import_index -= len( - categorized_comments["above"]["straight"].get(module, []) - ) - placed_module = finder(module) - if config.verbose and not config.only_modified: - print(f"else-type place_module for {module} returned {placed_module}") - - elif config.verbose: - verbose_output.append( - f"else-type place_module for {module} returned {placed_module}" - ) - if placed_module == "": - warn( - f"could not place module {module} of line {line} --" - " Do you need to define a default section?" - ) - imports.setdefault("", {"straight": OrderedDict(), "from": OrderedDict()}) - straight_import |= imports[placed_module][type_of_import].get( # type: ignore - module, False - ) - imports[placed_module][type_of_import][module] = straight_import # type: ignore - - change_count = len(out_lines) - original_line_count - - return ParsedContent( - in_lines=in_lines, - lines_without_imports=out_lines, - import_index=import_index, - place_imports=place_imports, - import_placements=import_placements, - as_map=as_map, - imports=imports, - categorized_comments=categorized_comments, - change_count=change_count, - original_line_count=original_line_count, - line_separator=line_separator, - sections=config.sections, - verbose_output=verbose_output, - ) diff --git a/env/lib/python3.8/site-packages/isort/place.py b/env/lib/python3.8/site-packages/isort/place.py deleted file mode 100644 index aaf954aa..00000000 --- a/env/lib/python3.8/site-packages/isort/place.py +++ /dev/null @@ -1,145 +0,0 @@ -"""Contains all logic related to placing an import within a certain section.""" -import importlib -from fnmatch import fnmatch -from functools import lru_cache -from pathlib import Path -from typing import FrozenSet, Iterable, Optional, Tuple - -from isort import sections -from isort.settings import DEFAULT_CONFIG, Config -from isort.utils import exists_case_sensitive - -LOCAL = "LOCALFOLDER" - - -def module(name: str, config: Config = DEFAULT_CONFIG) -> str: - """Returns the section placement for the given module name.""" - return module_with_reason(name, config)[0] - - -@lru_cache(maxsize=1000) -def module_with_reason(name: str, config: Config = DEFAULT_CONFIG) -> Tuple[str, str]: - """Returns the section placement for the given module name alongside the reasoning.""" - return ( - _forced_separate(name, config) - or _local(name, config) - or _known_pattern(name, config) - or _src_path(name, config) - or (config.default_section, "Default option in Config or universal default.") - ) - - -def _forced_separate(name: str, config: Config) -> Optional[Tuple[str, str]]: - for forced_separate in config.forced_separate: - # Ensure all forced_separate patterns will match to end of string - path_glob = forced_separate - if not forced_separate.endswith("*"): - path_glob = "%s*" % forced_separate - - if fnmatch(name, path_glob) or fnmatch(name, "." + path_glob): - return (forced_separate, f"Matched forced_separate ({forced_separate}) config value.") - - return None - - -def _local(name: str, config: Config) -> Optional[Tuple[str, str]]: - if name.startswith("."): - return (LOCAL, "Module name started with a dot.") - - return None - - -def _known_pattern(name: str, config: Config) -> Optional[Tuple[str, str]]: - parts = name.split(".") - module_names_to_check = (".".join(parts[:first_k]) for first_k in range(len(parts), 0, -1)) - for module_name_to_check in module_names_to_check: - for pattern, placement in config.known_patterns: - if placement in config.sections and pattern.match(module_name_to_check): - return (placement, f"Matched configured known pattern {pattern}") - - return None - - -def _src_path( - name: str, - config: Config, - src_paths: Optional[Iterable[Path]] = None, - prefix: Tuple[str, ...] = (), -) -> Optional[Tuple[str, str]]: - if src_paths is None: - src_paths = config.src_paths - - root_module_name, *nested_module = name.split(".", 1) - new_prefix = prefix + (root_module_name,) - namespace = ".".join(new_prefix) - - for src_path in src_paths: - module_path = (src_path / root_module_name).resolve() - if not prefix and not module_path.is_dir() and src_path.name == root_module_name: - module_path = src_path.resolve() - if nested_module and ( - namespace in config.namespace_packages - or ( - config.auto_identify_namespace_packages - and _is_namespace_package(module_path, config.supported_extensions) - ) - ): - return _src_path(nested_module[0], config, (module_path,), new_prefix) - if ( - _is_module(module_path) - or _is_package(module_path) - or _src_path_is_module(src_path, root_module_name) - ): - return (sections.FIRSTPARTY, f"Found in one of the configured src_paths: {src_path}.") - - return None - - -def _is_module(path: Path) -> bool: - return ( - exists_case_sensitive(str(path.with_suffix(".py"))) - or any( - exists_case_sensitive(str(path.with_suffix(ext_suffix))) - for ext_suffix in importlib.machinery.EXTENSION_SUFFIXES - ) - or exists_case_sensitive(str(path / "__init__.py")) - ) - - -def _is_package(path: Path) -> bool: - return exists_case_sensitive(str(path)) and path.is_dir() - - -def _is_namespace_package(path: Path, src_extensions: FrozenSet[str]) -> bool: - if not _is_package(path): - return False - - init_file = path / "__init__.py" - if not init_file.exists(): - filenames = [ - filepath - for filepath in path.iterdir() - if filepath.suffix.lstrip(".") in src_extensions - or filepath.name.lower() in ("setup.cfg", "pyproject.toml") - ] - if filenames: - return False - else: - with init_file.open() as open_init_file: - file_start = open_init_file.read(4096) - if ( - "__import__('pkg_resources').declare_namespace(__name__)" not in file_start - and '__import__("pkg_resources").declare_namespace(__name__)' not in file_start - and "__path__ = __import__('pkgutil').extend_path(__path__, __name__)" - not in file_start - and '__path__ = __import__("pkgutil").extend_path(__path__, __name__)' - not in file_start - ): - return False - return True - - -def _src_path_is_module(src_path: Path, module_name: str) -> bool: - return ( - module_name == src_path.name and src_path.is_dir() and exists_case_sensitive(str(src_path)) - ) diff --git a/env/lib/python3.8/site-packages/isort/profiles.py b/env/lib/python3.8/site-packages/isort/profiles.py deleted file mode 100644 index cb8cb568..00000000 --- a/env/lib/python3.8/site-packages/isort/profiles.py +++ /dev/null @@ -1,68 +0,0 @@ -"""Common profiles are defined here to be easily used within a project using --profile {name}""" -from typing import Any, Dict - -black = { - "multi_line_output": 3, - "include_trailing_comma": True, - "force_grid_wrap": 0, - "use_parentheses": True, - "ensure_newline_before_comments": True, - "line_length": 88, -} -django = { - "combine_as_imports": True, - "include_trailing_comma": True, - "multi_line_output": 5, - "line_length": 79, -} -pycharm = { - "multi_line_output": 3, - "force_grid_wrap": 2, - "lines_after_imports": 2, -} -google = { - "force_single_line": True, - "force_sort_within_sections": True, - "lexicographical": True, - "single_line_exclusions": ("typing",), - "order_by_type": False, - "group_by_package": True, -} -open_stack = { - "force_single_line": True, - "force_sort_within_sections": True, - "lexicographical": True, -} -plone = { - "force_alphabetical_sort": True, - "force_single_line": True, - "lines_after_imports": 2, - "line_length": 200, -} -attrs = { - "atomic": True, - "force_grid_wrap": 0, - "include_trailing_comma": True, - "lines_after_imports": 2, - "lines_between_types": 1, - "multi_line_output": 3, - "use_parentheses": True, -} -hug = { - "multi_line_output": 3, - "include_trailing_comma": True, - "force_grid_wrap": 0, - "use_parentheses": True, - "line_length": 100, -} - -profiles: Dict[str, Dict[str, Any]] = { - "black": black, - "django": django, - "pycharm": pycharm, - "google": google, - "open_stack": open_stack, - "plone": plone, - "attrs": attrs, - "hug": hug, -} diff --git a/env/lib/python3.8/site-packages/isort/pylama_isort.py b/env/lib/python3.8/site-packages/isort/pylama_isort.py deleted file mode 100644 index 4d4ffb92..00000000 --- a/env/lib/python3.8/site-packages/isort/pylama_isort.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sys -from contextlib import contextmanager -from typing import Any, Dict, List - -from pylama.lint import Linter as BaseLinter - -from isort.exceptions import FileSkipped - -from . import api - - -@contextmanager -def supress_stdout(): - stdout = sys.stdout - with open(os.devnull, "w") as devnull: - sys.stdout = devnull - yield - sys.stdout = stdout - - -class Linter(BaseLinter): - def allow(self, path: str) -> bool: - """Determine if this path should be linted.""" - return path.endswith(".py") - - def run(self, path: str, **meta: Any) -> List[Dict[str, Any]]: - """Lint the file. Return an array of error dicts if appropriate.""" - with supress_stdout(): - try: - if not api.check_file(path, disregard_skip=False): - return [ - { - "lnum": 0, - "col": 0, - "text": "Incorrectly sorted imports.", - "type": "ISORT", - } - ] - except FileSkipped: - pass - - return [] diff --git a/env/lib/python3.8/site-packages/isort/sections.py b/env/lib/python3.8/site-packages/isort/sections.py deleted file mode 100644 index f59db692..00000000 --- a/env/lib/python3.8/site-packages/isort/sections.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Defines all sections isort uses by default""" -from typing import Tuple - -FUTURE: str = "FUTURE" -STDLIB: str = "STDLIB" -THIRDPARTY: str = "THIRDPARTY" -FIRSTPARTY: str = "FIRSTPARTY" -LOCALFOLDER: str = "LOCALFOLDER" -DEFAULT: Tuple[str, ...] = (FUTURE, STDLIB, THIRDPARTY, FIRSTPARTY, LOCALFOLDER) diff --git a/env/lib/python3.8/site-packages/isort/settings.py b/env/lib/python3.8/site-packages/isort/settings.py deleted file mode 100644 index 96fc9410..00000000 --- a/env/lib/python3.8/site-packages/isort/settings.py +++ /dev/null @@ -1,739 +0,0 @@ -"""isort/settings.py. - -Defines how the default settings for isort should be loaded -""" -import configparser -import fnmatch -import os -import posixpath -import re -import stat -import subprocess # nosec: Needed for gitignore support. -import sys -from functools import lru_cache -from pathlib import Path -from typing import Any, Callable, Dict, FrozenSet, Iterable, List, Optional, Pattern, Set, Tuple -from warnings import warn - -from . import stdlibs -from ._future import dataclass, field -from ._vendored import toml -from .exceptions import ( - FormattingPluginDoesNotExist, - InvalidSettingsPath, - ProfileDoesNotExist, - UnsupportedSettings, -) -from .profiles import profiles -from .sections import DEFAULT as SECTION_DEFAULTS -from .sections import FIRSTPARTY, FUTURE, LOCALFOLDER, STDLIB, THIRDPARTY -from .wrap_modes import WrapModes -from .wrap_modes import from_string as wrap_mode_from_string - -_SHEBANG_RE = re.compile(br"^#!.*\bpython[23w]?\b") -SUPPORTED_EXTENSIONS = frozenset({"py", "pyi", "pyx", "pxd"}) -BLOCKED_EXTENSIONS = frozenset({"pex"}) -FILE_SKIP_COMMENTS: Tuple[str, ...] = ( - "isort:" + "skip_file", - "isort: " + "skip_file", -) # Concatenated to avoid this file being skipped -MAX_CONFIG_SEARCH_DEPTH: int = 25 # The number of parent directories to for a config file within -STOP_CONFIG_SEARCH_ON_DIRS: Tuple[str, ...] = (".git", ".hg") -VALID_PY_TARGETS: Tuple[str, ...] = tuple( - target.replace("py", "") for target in dir(stdlibs) if not target.startswith("_") -) -CONFIG_SOURCES: Tuple[str, ...] = ( - ".isort.cfg", - "pyproject.toml", - "setup.cfg", - "tox.ini", - ".editorconfig", -) -DEFAULT_SKIP: FrozenSet[str] = frozenset( - { - ".venv", - "venv", - ".tox", - ".eggs", - ".git", - ".hg", - ".mypy_cache", - ".nox", - ".svn", - ".bzr", - "_build", - "buck-out", - "build", - "dist", - ".pants.d", - ".direnv", - "node_modules", - } -) - -CONFIG_SECTIONS: Dict[str, Tuple[str, ...]] = { - ".isort.cfg": ("settings", "isort"), - "pyproject.toml": ("tool.isort",), - "setup.cfg": ("isort", "tool:isort"), - "tox.ini": ("isort", "tool:isort"), - ".editorconfig": ("*", "*.py", "**.py", "*.{py}"), -} -FALLBACK_CONFIG_SECTIONS: Tuple[str, ...] = ("isort", "tool:isort", "tool.isort") - -IMPORT_HEADING_PREFIX = "import_heading_" -KNOWN_PREFIX = "known_" -KNOWN_SECTION_MAPPING: Dict[str, str] = { - STDLIB: "STANDARD_LIBRARY", - FUTURE: "FUTURE_LIBRARY", - FIRSTPARTY: "FIRST_PARTY", - THIRDPARTY: "THIRD_PARTY", - LOCALFOLDER: "LOCAL_FOLDER", -} - -RUNTIME_SOURCE = "runtime" - -DEPRECATED_SETTINGS = ("not_skip", "keep_direct_and_as_imports") - -_STR_BOOLEAN_MAPPING = { - "y": True, - "yes": True, - "t": True, - "on": True, - "1": True, - "true": True, - "n": False, - "no": False, - "f": False, - "off": False, - "0": False, - "false": False, -} - - -@dataclass(frozen=True) -class _Config: - """Defines the data schema and defaults used for isort configuration. - - NOTE: known lists, such as known_standard_library, are intentionally not complete as they are - dynamically determined later on. - """ - - py_version: str = "3" - force_to_top: FrozenSet[str] = frozenset() - skip: FrozenSet[str] = DEFAULT_SKIP - skip_glob: FrozenSet[str] = frozenset() - skip_gitignore: bool = False - line_length: int = 79 - wrap_length: int = 0 - line_ending: str = "" - sections: Tuple[str, ...] = SECTION_DEFAULTS - no_sections: bool = False - known_future_library: FrozenSet[str] = frozenset(("__future__",)) - known_third_party: FrozenSet[str] = frozenset() - known_first_party: FrozenSet[str] = frozenset() - known_local_folder: FrozenSet[str] = frozenset() - known_standard_library: FrozenSet[str] = frozenset() - extra_standard_library: FrozenSet[str] = frozenset() - known_other: Dict[str, FrozenSet[str]] = field(default_factory=dict) - multi_line_output: WrapModes = WrapModes.GRID # type: ignore - forced_separate: Tuple[str, ...] = () - indent: str = " " * 4 - comment_prefix: str = " #" - length_sort: bool = False - length_sort_straight: bool = False - length_sort_sections: FrozenSet[str] = frozenset() - add_imports: FrozenSet[str] = frozenset() - remove_imports: FrozenSet[str] = frozenset() - append_only: bool = False - reverse_relative: bool = False - force_single_line: bool = False - single_line_exclusions: Tuple[str, ...] = () - default_section: str = THIRDPARTY - import_headings: Dict[str, str] = field(default_factory=dict) - balanced_wrapping: bool = False - use_parentheses: bool = False - order_by_type: bool = True - atomic: bool = False - lines_after_imports: int = -1 - lines_between_sections: int = 1 - lines_between_types: int = 0 - combine_as_imports: bool = False - combine_star: bool = False - include_trailing_comma: bool = False - from_first: bool = False - verbose: bool = False - quiet: bool = False - force_adds: bool = False - force_alphabetical_sort_within_sections: bool = False - force_alphabetical_sort: bool = False - force_grid_wrap: int = 0 - force_sort_within_sections: bool = False - lexicographical: bool = False - group_by_package: bool = False - ignore_whitespace: bool = False - no_lines_before: FrozenSet[str] = frozenset() - no_inline_sort: bool = False - ignore_comments: bool = False - case_sensitive: bool = False - sources: Tuple[Dict[str, Any], ...] = () - virtual_env: str = "" - conda_env: str = "" - ensure_newline_before_comments: bool = False - directory: str = "" - profile: str = "" - honor_noqa: bool = False - src_paths: Tuple[Path, ...] = () - old_finders: bool = False - remove_redundant_aliases: bool = False - float_to_top: bool = False - filter_files: bool = False - formatter: str = "" - formatting_function: Optional[Callable[[str, str, object], str]] = None - color_output: bool = False - treat_comments_as_code: FrozenSet[str] = frozenset() - treat_all_comments_as_code: bool = False - supported_extensions: FrozenSet[str] = SUPPORTED_EXTENSIONS - blocked_extensions: FrozenSet[str] = BLOCKED_EXTENSIONS - constants: FrozenSet[str] = frozenset() - classes: FrozenSet[str] = frozenset() - variables: FrozenSet[str] = frozenset() - dedup_headings: bool = False - only_sections: bool = False - only_modified: bool = False - auto_identify_namespace_packages: bool = True - namespace_packages: FrozenSet[str] = frozenset() - - def __post_init__(self): - py_version = self.py_version - if py_version == "auto": # pragma: no cover - if sys.version_info.major == 2 and sys.version_info.minor <= 6: - py_version = "2" - elif sys.version_info.major == 3 and ( - sys.version_info.minor <= 5 or sys.version_info.minor >= 9 - ): - py_version = "3" - else: - py_version = f"{sys.version_info.major}{sys.version_info.minor}" - - if py_version not in VALID_PY_TARGETS: - raise ValueError( - f"The python version {py_version} is not supported. " - "You can set a python version with the -py or --python-version flag. " - f"The following versions are supported: {VALID_PY_TARGETS}" - ) - - if py_version != "all": - object.__setattr__(self, "py_version", f"py{py_version}") - - if not self.known_standard_library: - object.__setattr__( - self, "known_standard_library", frozenset(getattr(stdlibs, self.py_version).stdlib) - ) - - if self.force_alphabetical_sort: - object.__setattr__(self, "force_alphabetical_sort_within_sections", True) - object.__setattr__(self, "no_sections", True) - object.__setattr__(self, "lines_between_types", 1) - object.__setattr__(self, "from_first", True) - if self.wrap_length > self.line_length: - raise ValueError( - "wrap_length must be set lower than or equal to line_length: " - f"{self.wrap_length} > {self.line_length}." - ) - - def __hash__(self): - return id(self) - - -_DEFAULT_SETTINGS = {**vars(_Config()), "source": "defaults"} - - -class Config(_Config): - def __init__( - self, - settings_file: str = "", - settings_path: str = "", - config: Optional[_Config] = None, - **config_overrides, - ): - self._known_patterns: Optional[List[Tuple[Pattern[str], str]]] = None - self._section_comments: Optional[Tuple[str, ...]] = None - - if config: - config_vars = vars(config).copy() - config_vars.update(config_overrides) - config_vars["py_version"] = config_vars["py_version"].replace("py", "") - config_vars.pop("_known_patterns") - config_vars.pop("_section_comments") - super().__init__(**config_vars) # type: ignore - return - - # We can't use self.quiet to conditionally show warnings before super.__init__() is called - # at the end of this method. _Config is also frozen so setting self.quiet isn't possible. - # Therefore we extract quiet early here in a variable and use that in warning conditions. - quiet = config_overrides.get("quiet", False) - - sources: List[Dict[str, Any]] = [_DEFAULT_SETTINGS] - - config_settings: Dict[str, Any] - project_root: str - if settings_file: - config_settings = _get_config_data( - settings_file, - CONFIG_SECTIONS.get(os.path.basename(settings_file), FALLBACK_CONFIG_SECTIONS), - ) - project_root = os.path.dirname(settings_file) - if not config_settings and not quiet: - warn( - f"A custom settings file was specified: {settings_file} but no configuration " - "was found inside. This can happen when [settings] is used as the config " - "header instead of [isort]. " - "See: https://pycqa.github.io/isort/docs/configuration/config_files" - "/#custom_config_files for more information." - ) - elif settings_path: - if not os.path.exists(settings_path): - raise InvalidSettingsPath(settings_path) - - settings_path = os.path.abspath(settings_path) - project_root, config_settings = _find_config(settings_path) - else: - config_settings = {} - project_root = os.getcwd() - - profile_name = config_overrides.get("profile", config_settings.get("profile", "")) - profile: Dict[str, Any] = {} - if profile_name: - if profile_name not in profiles: - import pkg_resources - - for plugin in pkg_resources.iter_entry_points("isort.profiles"): - profiles.setdefault(plugin.name, plugin.load()) - - if profile_name not in profiles: - raise ProfileDoesNotExist(profile_name) - - profile = profiles[profile_name].copy() - profile["source"] = f"{profile_name} profile" - sources.append(profile) - - if config_settings: - sources.append(config_settings) - if config_overrides: - config_overrides["source"] = RUNTIME_SOURCE - sources.append(config_overrides) - - combined_config = {**profile, **config_settings, **config_overrides} - if "indent" in combined_config: - indent = str(combined_config["indent"]) - if indent.isdigit(): - indent = " " * int(indent) - else: - indent = indent.strip("'").strip('"') - if indent.lower() == "tab": - indent = "\t" - combined_config["indent"] = indent - - known_other = {} - import_headings = {} - for key, value in tuple(combined_config.items()): - # Collect all known sections beyond those that have direct entries - if key.startswith(KNOWN_PREFIX) and key not in ( - "known_standard_library", - "known_future_library", - "known_third_party", - "known_first_party", - "known_local_folder", - ): - import_heading = key[len(KNOWN_PREFIX) :].lower() - maps_to_section = import_heading.upper() - combined_config.pop(key) - if maps_to_section in KNOWN_SECTION_MAPPING: - section_name = f"known_{KNOWN_SECTION_MAPPING[maps_to_section].lower()}" - if section_name in combined_config and not quiet: - warn( - f"Can't set both {key} and {section_name} in the same config file.\n" - f"Default to {section_name} if unsure." - "\n\n" - "See: https://pycqa.github.io/isort/" - "#custom-sections-and-ordering." - ) - else: - combined_config[section_name] = frozenset(value) - else: - known_other[import_heading] = frozenset(value) - if maps_to_section not in combined_config.get("sections", ()) and not quiet: - warn( - f"`{key}` setting is defined, but {maps_to_section} is not" - " included in `sections` config option:" - f" {combined_config.get('sections', SECTION_DEFAULTS)}.\n\n" - "See: https://pycqa.github.io/isort/" - "#custom-sections-and-ordering." - ) - if key.startswith(IMPORT_HEADING_PREFIX): - import_headings[key[len(IMPORT_HEADING_PREFIX) :].lower()] = str(value) - - # Coerce all provided config values into their correct type - default_value = _DEFAULT_SETTINGS.get(key, None) - if default_value is None: - continue - - combined_config[key] = type(default_value)(value) - - for section in combined_config.get("sections", ()): - if section in SECTION_DEFAULTS: - continue - elif not section.lower() in known_other: - config_keys = ", ".join(known_other.keys()) - warn( - f"`sections` setting includes {section}, but no known_{section.lower()} " - "is defined. " - f"The following known_SECTION config options are defined: {config_keys}." - ) - - if "directory" not in combined_config: - combined_config["directory"] = ( - os.path.dirname(config_settings["source"]) - if config_settings.get("source", None) - else os.getcwd() - ) - - path_root = Path(combined_config.get("directory", project_root)).resolve() - path_root = path_root if path_root.is_dir() else path_root.parent - if "src_paths" not in combined_config: - combined_config["src_paths"] = (path_root / "src", path_root) - else: - src_paths: List[Path] = [] - for src_path in combined_config.get("src_paths", ()): - full_path = path_root / src_path - if full_path not in src_paths: - src_paths.append(full_path) - - combined_config["src_paths"] = tuple(src_paths) - - if "formatter" in combined_config: - import pkg_resources - - for plugin in pkg_resources.iter_entry_points("isort.formatters"): - if plugin.name == combined_config["formatter"]: - combined_config["formatting_function"] = plugin.load() - break - else: - raise FormattingPluginDoesNotExist(combined_config["formatter"]) - - # Remove any config values that are used for creating config object but - # aren't defined in dataclass - combined_config.pop("source", None) - combined_config.pop("sources", None) - combined_config.pop("runtime_src_paths", None) - - deprecated_options_used = [ - option for option in combined_config if option in DEPRECATED_SETTINGS - ] - if deprecated_options_used: - for deprecated_option in deprecated_options_used: - combined_config.pop(deprecated_option) - if not quiet: - warn( - "W0503: Deprecated config options were used: " - f"{', '.join(deprecated_options_used)}." - "Please see the 5.0.0 upgrade guide: bit.ly/isortv5." - ) - - if known_other: - combined_config["known_other"] = known_other - if import_headings: - for import_heading_key in import_headings: - combined_config.pop(f"{IMPORT_HEADING_PREFIX}{import_heading_key}") - combined_config["import_headings"] = import_headings - - unsupported_config_errors = {} - for option in set(combined_config.keys()).difference( - getattr(_Config, "__dataclass_fields__", {}).keys() - ): - for source in reversed(sources): - if option in source: - unsupported_config_errors[option] = { - "value": source[option], - "source": source["source"], - } - if unsupported_config_errors: - raise UnsupportedSettings(unsupported_config_errors) - - super().__init__(sources=tuple(sources), **combined_config) # type: ignore - - def is_supported_filetype(self, file_name: str): - _root, ext = os.path.splitext(file_name) - ext = ext.lstrip(".") - if ext in self.supported_extensions: - return True - elif ext in self.blocked_extensions: - return False - - # Skip editor backup files. - if file_name.endswith("~"): - return False - - try: - if stat.S_ISFIFO(os.stat(file_name).st_mode): - return False - except OSError: - pass - - try: - with open(file_name, "rb") as fp: - line = fp.readline(100) - except OSError: - return False - else: - return bool(_SHEBANG_RE.match(line)) - - def is_skipped(self, file_path: Path) -> bool: - """Returns True if the file and/or folder should be skipped based on current settings.""" - if self.directory and Path(self.directory) in file_path.resolve().parents: - file_name = os.path.relpath(file_path.resolve(), self.directory) - else: - file_name = str(file_path) - - os_path = str(file_path) - - if self.skip_gitignore: - if file_path.name == ".git": # pragma: no cover - return True - - result = subprocess.run( # nosec - ["git", "-C", str(file_path.parent), "check-ignore", "--quiet", os_path] - ) - if result.returncode == 0: - return True - - normalized_path = os_path.replace("\\", "/") - if normalized_path[1:2] == ":": - normalized_path = normalized_path[2:] - - for skip_path in self.skip: - if posixpath.abspath(normalized_path) == posixpath.abspath( - skip_path.replace("\\", "/") - ): - return True - - position = os.path.split(file_name) - while position[1]: - if position[1] in self.skip: - return True - position = os.path.split(position[0]) - - for glob in self.skip_glob: - if fnmatch.fnmatch(file_name, glob) or fnmatch.fnmatch("/" + file_name, glob): - return True - - if not (os.path.isfile(os_path) or os.path.isdir(os_path) or os.path.islink(os_path)): - return True - - return False - - @property - def known_patterns(self): - if self._known_patterns is not None: - return self._known_patterns - - self._known_patterns = [] - pattern_sections = [STDLIB] + [section for section in self.sections if section != STDLIB] - for placement in reversed(pattern_sections): - known_placement = KNOWN_SECTION_MAPPING.get(placement, placement).lower() - config_key = f"{KNOWN_PREFIX}{known_placement}" - known_modules = getattr(self, config_key, self.known_other.get(known_placement, ())) - extra_modules = getattr(self, f"extra_{known_placement}", ()) - all_modules = set(extra_modules).union(known_modules) - known_patterns = [ - pattern - for known_pattern in all_modules - for pattern in self._parse_known_pattern(known_pattern) - ] - for known_pattern in known_patterns: - regexp = "^" + known_pattern.replace("*", ".*").replace("?", ".?") + "$" - self._known_patterns.append((re.compile(regexp), placement)) - - return self._known_patterns - - @property - def section_comments(self) -> Tuple[str, ...]: - if self._section_comments is not None: - return self._section_comments - - self._section_comments = tuple(f"# {heading}" for heading in self.import_headings.values()) - return self._section_comments - - def _parse_known_pattern(self, pattern: str) -> List[str]: - """Expand pattern if identified as a directory and return found sub packages""" - if pattern.endswith(os.path.sep): - patterns = [ - filename - for filename in os.listdir(os.path.join(self.directory, pattern)) - if os.path.isdir(os.path.join(self.directory, pattern, filename)) - ] - else: - patterns = [pattern] - - return patterns - - -def _get_str_to_type_converter(setting_name: str) -> Callable[[str], Any]: - type_converter: Callable[[str], Any] = type(_DEFAULT_SETTINGS.get(setting_name, "")) - if type_converter == WrapModes: - type_converter = wrap_mode_from_string - return type_converter - - -def _as_list(value: str) -> List[str]: - if isinstance(value, list): - return [item.strip() for item in value] - filtered = [item.strip() for item in value.replace("\n", ",").split(",") if item.strip()] - return filtered - - -def _abspaths(cwd: str, values: Iterable[str]) -> Set[str]: - paths = { - os.path.join(cwd, value) - if not value.startswith(os.path.sep) and value.endswith(os.path.sep) - else value - for value in values - } - return paths - - -@lru_cache() -def _find_config(path: str) -> Tuple[str, Dict[str, Any]]: - current_directory = path - tries = 0 - while current_directory and tries < MAX_CONFIG_SEARCH_DEPTH: - for config_file_name in CONFIG_SOURCES: - potential_config_file = os.path.join(current_directory, config_file_name) - if os.path.isfile(potential_config_file): - config_data: Dict[str, Any] - try: - config_data = _get_config_data( - potential_config_file, CONFIG_SECTIONS[config_file_name] - ) - except Exception: - warn(f"Failed to pull configuration information from {potential_config_file}") - config_data = {} - if config_data: - return (current_directory, config_data) - - for stop_dir in STOP_CONFIG_SEARCH_ON_DIRS: - if os.path.isdir(os.path.join(current_directory, stop_dir)): - return (current_directory, {}) - - new_directory = os.path.split(current_directory)[0] - if new_directory == current_directory: - break - - current_directory = new_directory - tries += 1 - - return (path, {}) - - -@lru_cache() -def _get_config_data(file_path: str, sections: Tuple[str]) -> Dict[str, Any]: - settings: Dict[str, Any] = {} - - with open(file_path) as config_file: - if file_path.endswith(".toml"): - config = toml.load(config_file) - for section in sections: - config_section = config - for key in section.split("."): - config_section = config_section.get(key, {}) - settings.update(config_section) - else: - if file_path.endswith(".editorconfig"): - line = "\n" - last_position = config_file.tell() - while line: - line = config_file.readline() - if "[" in line: - config_file.seek(last_position) - break - last_position = config_file.tell() - - config = configparser.ConfigParser(strict=False) - config.read_file(config_file) - for section in sections: - if section.startswith("*.{") and section.endswith("}"): - extension = section[len("*.{") : -1] - for config_key in config.keys(): - if config_key.startswith("*.{") and config_key.endswith("}"): - if extension in map( - lambda text: text.strip(), config_key[len("*.{") : -1].split(",") - ): - settings.update(config.items(config_key)) - - elif config.has_section(section): - settings.update(config.items(section)) - - if settings: - settings["source"] = file_path - - if file_path.endswith(".editorconfig"): - indent_style = settings.pop("indent_style", "").strip() - indent_size = settings.pop("indent_size", "").strip() - if indent_size == "tab": - indent_size = settings.pop("tab_width", "").strip() - - if indent_style == "space": - settings["indent"] = " " * (indent_size and int(indent_size) or 4) - - elif indent_style == "tab": - settings["indent"] = "\t" * (indent_size and int(indent_size) or 1) - - max_line_length = settings.pop("max_line_length", "").strip() - if max_line_length and (max_line_length == "off" or max_line_length.isdigit()): - settings["line_length"] = ( - float("inf") if max_line_length == "off" else int(max_line_length) - ) - settings = { - key: value - for key, value in settings.items() - if key in _DEFAULT_SETTINGS.keys() or key.startswith(KNOWN_PREFIX) - } - - for key, value in settings.items(): - existing_value_type = _get_str_to_type_converter(key) - if existing_value_type == tuple: - settings[key] = tuple(_as_list(value)) - elif existing_value_type == frozenset: - settings[key] = frozenset(_as_list(settings.get(key))) # type: ignore - elif existing_value_type == bool: - # Only some configuration formats support native boolean values. - if not isinstance(value, bool): - value = _as_bool(value) - settings[key] = value - elif key.startswith(KNOWN_PREFIX): - settings[key] = _abspaths(os.path.dirname(file_path), _as_list(value)) - elif key == "force_grid_wrap": - try: - result = existing_value_type(value) - except ValueError: # backwards compatibility for true / false force grid wrap - result = 0 if value.lower().strip() == "false" else 2 - settings[key] = result - elif key == "comment_prefix": - settings[key] = str(value).strip("'").strip('"') - else: - settings[key] = existing_value_type(value) - - return settings - - -def _as_bool(value: str) -> bool: - """Given a string value that represents True or False, returns the Boolean equivalent. - Heavily inspired from distutils strtobool. - """ - try: - return _STR_BOOLEAN_MAPPING[value.lower()] - except KeyError: - raise ValueError(f"invalid truth value {value}") - - -DEFAULT_CONFIG = Config() diff --git a/env/lib/python3.8/site-packages/isort/setuptools_commands.py b/env/lib/python3.8/site-packages/isort/setuptools_commands.py deleted file mode 100644 index 96e41dd0..00000000 --- a/env/lib/python3.8/site-packages/isort/setuptools_commands.py +++ /dev/null @@ -1,61 +0,0 @@ -import glob -import os -import sys -from typing import Any, Dict, Iterator, List -from warnings import warn - -import setuptools - -from . import api -from .settings import DEFAULT_CONFIG - - -class ISortCommand(setuptools.Command): - """The :class:`ISortCommand` class is used by setuptools to perform - imports checks on registered modules. - """ - - description = "Run isort on modules registered in setuptools" - user_options: List[Any] = [] - - def initialize_options(self) -> None: - default_settings = vars(DEFAULT_CONFIG).copy() - for key, value in default_settings.items(): - setattr(self, key, value) - - def finalize_options(self) -> None: - "Get options from config files." - self.arguments: Dict[str, Any] = {} # skipcq: PYL-W0201 - self.arguments["settings_path"] = os.getcwd() - - def distribution_files(self) -> Iterator[str]: - """Find distribution packages.""" - # This is verbatim from flake8 - if self.distribution.packages: # pragma: no cover - package_dirs = self.distribution.package_dir or {} - for package in self.distribution.packages: - pkg_dir = package - if package in package_dirs: - pkg_dir = package_dirs[package] - elif "" in package_dirs: # pragma: no cover - pkg_dir = package_dirs[""] + os.path.sep + pkg_dir - yield pkg_dir.replace(".", os.path.sep) - - if self.distribution.py_modules: - for filename in self.distribution.py_modules: - yield "%s.py" % filename - # Don't miss the setup.py file itself - yield "setup.py" - - def run(self) -> None: - arguments = self.arguments - wrong_sorted_files = False - for path in self.distribution_files(): - for python_file in glob.iglob(os.path.join(path, "*.py")): - try: - if not api.check_file(python_file, **arguments): - wrong_sorted_files = True # pragma: no cover - except OSError as error: # pragma: no cover - warn(f"Unable to parse file {python_file} due to {error}") - if wrong_sorted_files: - sys.exit(1) # pragma: no cover diff --git a/env/lib/python3.8/site-packages/isort/sorting.py b/env/lib/python3.8/site-packages/isort/sorting.py deleted file mode 100644 index cab77011..00000000 --- a/env/lib/python3.8/site-packages/isort/sorting.py +++ /dev/null @@ -1,102 +0,0 @@ -import re -from typing import Any, Callable, Iterable, List, Optional - -from .settings import Config - -_import_line_intro_re = re.compile("^(?:from|import) ") -_import_line_midline_import_re = re.compile(" import ") - - -def module_key( - module_name: str, - config: Config, - sub_imports: bool = False, - ignore_case: bool = False, - section_name: Optional[Any] = None, - straight_import: Optional[bool] = False, -) -> str: - match = re.match(r"^(\.+)\s*(.*)", module_name) - if match: - sep = " " if config.reverse_relative else "_" - module_name = sep.join(match.groups()) - - prefix = "" - if ignore_case: - module_name = str(module_name).lower() - else: - module_name = str(module_name) - - if sub_imports and config.order_by_type: - if module_name in config.constants: - prefix = "A" - elif module_name in config.classes: - prefix = "B" - elif module_name in config.variables: - prefix = "C" - elif module_name.isupper() and len(module_name) > 1: # see issue #376 - prefix = "A" - elif module_name in config.classes or module_name[0:1].isupper(): - prefix = "B" - else: - prefix = "C" - if not config.case_sensitive: - module_name = module_name.lower() - - length_sort = ( - config.length_sort - or (config.length_sort_straight and straight_import) - or str(section_name).lower() in config.length_sort_sections - ) - _length_sort_maybe = length_sort and (str(len(module_name)) + ":" + module_name) or module_name - return f"{module_name in config.force_to_top and 'A' or 'B'}{prefix}{_length_sort_maybe}" - - -def section_key( - line: str, - order_by_type: bool, - force_to_top: List[str], - lexicographical: bool = False, - length_sort: bool = False, - reverse_relative: bool = False, - group_by_package: bool = False, -) -> str: - section = "B" - - if reverse_relative and line.startswith("from ."): - match = re.match(r"^from (\.+)\s*(.*)", line) - if match: # pragma: no cover - regex always matches if line starts with "from ." - line = f"from {' '.join(match.groups())}" - if group_by_package and line.strip().startswith("from"): - line = line.split(" import", 1)[0] - - if lexicographical: - line = _import_line_intro_re.sub("", _import_line_midline_import_re.sub(".", line)) - else: - line = re.sub("^from ", "", line) - line = re.sub("^import ", "", line) - if line.split(" ")[0] in force_to_top: - section = "A" - if not order_by_type: - line = line.lower() - - return f"{section}{len(line) if length_sort else ''}{line}" - - -def naturally(to_sort: Iterable[str], key: Optional[Callable[[str], Any]] = None) -> List[str]: - """Returns a naturally sorted list""" - if key is None: - key_callback = _natural_keys - else: - - def key_callback(text: str) -> List[Any]: - return _natural_keys(key(text)) # type: ignore - - return sorted(to_sort, key=key_callback) - - -def _atoi(text: str) -> Any: - return int(text) if text.isdigit() else text - - -def _natural_keys(text: str) -> List[Any]: - return [_atoi(c) for c in re.split(r"(\d+)", text)] diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__init__.py b/env/lib/python3.8/site-packages/isort/stdlibs/__init__.py deleted file mode 100644 index 9021bc45..00000000 --- a/env/lib/python3.8/site-packages/isort/stdlibs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import all, py2, py3, py27, py35, py36, py37, py38, py39 diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 4134edf2afbba358340d4b3847f27f5ceb5784fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmYk%u};G<5CBjoPMV~mACjRxL<9s0p?(1iV(}7%#%e5bc4WJi@+Eu&zrkl@WnyMy z!WR}S-SeGwwsp^&&6zP^l-f|)# zQes79L{1b04e`$G1?9v~54}MNP9CiEMoTy<-&i>s2PdsyY!AMd*y^p5_AD((eTG53 yz&QEd=xSGkQ(kUE-)no64wN(2gY#Wza?mtNhxeM@IL-Mzn(j2n2O9M|1p5U-)K?h* diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/all.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/all.cpython-38.pyc deleted file mode 100644 index 38491bc65b6927fc93e68d01a434dc4bd887aab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 zcmYjLOG*Pl5baM0A_Q`TY-f=aB%25l!~?hyH?s-jbdl-UKe{@BIf-ZR8XjY|uDpUP zt8wFldc`XquindIaVr@6_s`=U@2@KUL$P?^p%s%6MmphTE4^x!6e!Oc)mcA^RvYy! z8vQNV)~HFRaa(Ek)XXN4Yf9Ek)0~QN_Vq*LdA(Ko>0yW-fw0e5Vn8_Aa?F?_!6jHo zU0(+DU04(5D`voO1RN(m37R`)Do>549oH HLQC}vAK^jT diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py2.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py2.cpython-38.pyc deleted file mode 100644 index 2b8df2420972d2820eaf5c070358d51d187288cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 235 zcmYjLF>b;@5WG7Qgb;4?2N!rHQb2*CydX`KhQ>0!m3_p%JKY|Z{1V>4H}VX(RD2;7 zYiJm0XEoZ{-T6t9xnOKge|gINGKyy?7N1=7#-xRojcDagN`dmAc1o*nkxs6Xhp8N1 ze7{0i&}Bm5F&k?+A|8fG^5eV_VoIVdyXb w+79>z_&(OozGoXC6LHDD-=abSLoP&kJR)|jGT#rgZR_;0!H+Q*jae4z28w1qfdBvi diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py27.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py27.cpython-38.pyc deleted file mode 100644 index 772007c23d8119eae3236c074739ea33ff22d1b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4189 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 diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py35.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py35.cpython-38.pyc deleted file mode 100644 index e091cba1d4336391fca272966c7152d1a08d3aa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3055 zcmeHJXO|pD6&>x&^n_huat=dAVC{g`G6IY-AR9!G1eOU)SZey#OqZv-s#I0Iv$F)7 zoO3YI|%jEEU}N5 z;}v)%UWIFLEnbb+;I()iUXM56jd&B@jJM#ecpKi1ci^3P7v7Ec;JtVs-j5I9I(!fx z!iVt@d=wwU_4qhGfluO7_%uF)&*F3VJidS%@I~B+FX79$317ii@ilxM-@rHVE!>Q6 z<2(2+zK8GQ2lyd=gdgK4_$h9|&+v2n0>8ws@N4`Azs2wHd;9@^#GmkI+={>8HvARm zigVis@V6^lhyK2Q{qPD^%294~5K8+|DCEcop&=YbrJ6Y5mLoGAonD5*=+V~Z(aquT z_^Hv!Q)fn(A3t$sb97?*-w)-5&@<^T9Ep*Z3*P0!$QPzAF`CezlOjkAYp?XIxuBZ+ z09y2$b~*C7Q#Nc4dCug+mmNw9` z-=(dvv@+SOnJbzBlMqxTV;hqy_UMqRL`g+Wr|GUXl#c@rp$@9_Trhc%Ozj1?FA2*R zyRs6hj033|7bkd3YF|5Pm5m*#>xx^P(pU1kH`iu)%w{qe2HvBz!qayuDMzt0 zD-A=NIXX7mr+d9Z_#$1=Eu^q#W2dMDkyV7MOk>~ZzAZ&aHBTC`*SKs=Q-H2DUhTy} zBO13dYn@_8^cY9eh?ymO1@@;6Bm%oY9NOj1`97it%euJ$L`r$*3A6b+VGl~ zIpWe(ag7YoPjr)t6MKZQOI~owo7&|Jz?JF7QYKV(U9H)3UC$ySW?rU7j)RqCA9JdZ z#4^MnZ(t6&L?B$|-D<_pBCd6Um2TYe?Ibi1_K@hP&NKU?zb zR&0BEyw2f2fgW6a=tSkr#vpyJYSs2W*<_NohiPPrRbnC^n8;b=T#}YSH*+;(8Txv1 z9w+p()}rRpvYHrHi!z7_i`q_vHQ=z~rnJKo$+6F6Ewm;p1>u?+4T3C*wI-)QR<@b! zF_)DhkU9;=^i#Jk98o-2QGe4B4P9kvOynKrEPbj#FmtJCDG9aDWCjw1_g zMkT$m$znSY8(FB?y>ffFl8}|*xfMfFBy;PvR*9%dlp^-|K?))LWwk4l?`w4(J9Vu{ z>bp|!#{NP$&2tQ4Az1I;LW;SQ(>Pqn$;6ojix;zn(utY-lthze6&HS{(za|54bIwo zRk@vUa5mr0$Wg+w*C|)Yqq3r&*x9EWCl9UhRoo$*cXm?6(i3_^%iYTV%$nh!7#F6J zW4>RGq^RYXPty*|Yy6lYjV-CPAb;z_D{PG!%9wYIZS&%9Z5|sZfF9<)x!`*~R-Uvs oKL1v8*Va)!*s*`fifk_BKZ7lQ6UR<}?ZE$k|0gnVZR^H=0o_L~Jpcdz diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py36.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py36.cpython-38.pyc deleted file mode 100644 index b9e3422b2c4049b2c1fdeb033ea376345bf2ed68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3068 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 diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py38.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py38.cpython-38.pyc deleted file mode 100644 index 887dc44f1dbf644da026d9654167b6a6548f4d2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3077 zcmeHJSCGW)8*-|>aD8Y*;#^3 zFgYg^O%686WRt<|DZsck_Wx2c5GW9Kag7=%J4U0}L_380*-;LEHxC;kLLPZjU?Qj<^%< zjJx2jxEt<{d*Gh97w(PwV1oPNez-p#fCu71crYG!8ws@N4`Azs2wHd;9@^#GmkI zoXgLhJ%GPl(K+Vb%9ArgH{SJF|M7`^X7nZ z;XG*3ZC0y^%dD#W<~SVOLS2@tEuV7(!r<<|$LqglTDo)i<##A9mg_9Rv5V|SSFie#eE>nubO6PJnN+&ZOn%1iD z%o7*x9SOtiv^6v4kD4fCOj_t>a~1k*d`gkmdO=YNpL3=}=w$}9AKT2elIGVlQxr6y z438eNW2{@bFwRU_@pw@bQP){*t<*kjP@kzbXxq#%9M9avgLKq)n2%_yT7^Mut(?;h zyQ)0ha62^YSCxzo)J&WU>kwXKg>bPmWJh{c%Fsnxh5=nwr6{PV*(_S=Lb)(v<7=-9 z#|e{p$)ulm>teC6p)X6JiZGIz5p#gsq;|EHm8wEd>bm3-Yqbd*Gf@|wm_Z?J=+83k zX)z`@E2}Vyiqcihn$0xRndKZamYV1C(aehd>?Jc_MIT4AT4&xEy0I>=G?u`o!6V)r4WmM7nTaeXN(vKU z#W^#d$87eBy;6ihOlfL%TO||pr)0TvR;bqiZB(*$ZGC$sJq;VBL0!n1(qOWZ(y168 zK9(w^`_FR(YUxo6m$YqIkfXrIP3xno3&Xjg1=T;ssnYgpzTt zxmJ+GSu<|KAnuJuyA>~3QmJggz}8#YCZtbD5PXAbF^{MU!>SNImN;sJTH|tMn!NWb z)a~-Sb2op}0zKZ8iG_gC)SBd3wCR<37Kr5ZJ zJ2c*NF~ot}F1Yt-=sLQ-&gMT6A8b21k~_T`#co@)u5-~QvlYg%Wv*4^Cg+*ac^r$f zV)V^e%~-~+PWJ&rKWi;&POZw+uxylGq^xc?QrL)1%T{rPBa*|A(^_avYVyK1#Tt28 z5Ohs)y)3I{aKNONiiqkp+%k-}b!iFbQTrG)H=?1bB({;x{el>XrSN7UH7!M<_Lxjh zf{@%9MJlpISZ`F)8ZTMsdV(bJHE*vB<5ohJhWlEYq=@F$Ypo)6N45+@cE~=Yy`;89 z^nIhBU26r8#+9A8xTVWhhggF|C?!0Db~YBR~&x-9qq% spDIV%o9@5fTy^vqpYSlesAZjt`GMGRH?i#v*AD#u?|&o%*K}_D7Y6V;{{R30 diff --git a/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py39.cpython-38.pyc b/env/lib/python3.8/site-packages/isort/stdlibs/__pycache__/py39.cpython-38.pyc deleted file mode 100644 index 1dabe0a99f7031a3d5eefc6e0fc26f2781eb693e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3065 zcmeHJSCY%-Xfv&^X%9{3kLajSa|hX?)u=dgRWzOO>pm+p6KuRe5W+~Lo$>u=rq z`@v4bE6VJj` zIE$)m?MY6HCUiP2@Qh^+puu(sIh}3cCo@9 zUV@k6Wq3JWfot(fyb7DA&!0Ph+pg*y{@dOS<11AmCz;V+DD5UbmlNlOhOn3vDz(C{CT2D{v+}volg*9e z8{_eb)00!D&rYs5aq{fO31Reoa}k}aR}C_-1HS?CEh%fe9Dc_plqp)afzEABbZRkzYK>O<0K z%Iq&0E5m@sc2(S}p^T}*AQettd{OA8NW(ByTDVLpE-RhO-6);RcxhUz!ZR^ExOX%R zvoqGrm@sOhkTFZ4o6S||bMPreUh4%#DSXbI5}}tF(0&{<*GigS&rDI!fHJ&#$ceFT z<-#~KWyR}7QAAy5wY5_FaFF^;wL#lvhv9f8D_*3dzQcS(Th%HgakO$yH|(nNbi?h? zuwPX&I#4rlF04a%krl$l$&eH2RVhOkX&Dl_s!CB%QL|aJ(uHzi#KG5I6^vY7-95L|u4d0)@1pKg+bIftbsztimWNN>?>Y zG}FvpmUGQmYM#eOGb{F!HJJG-x-^>AI`hWRo3(is26O2RgH0$aM%5@WF`+jvOnPoO zx1!3MSmu_l&G+bFk_*?Y^>Znz?a<3hL6GIXEaK>Sf_Z4n4OBVL!D_4MEeB(p{3pal z6_K(=yp2>P04r&Jr093+Uhf)bbVwF*wKNtXp%X{F*$ksXX_<*ECp-!h@x(ndpEHf2 zSL~G{Br&H&XfkzHYlBnAye*T)`ts9 zmOxe3WOOl_>1*k27P^|{O|)(^JD`m4O<28D5>`V~Nh`duQR80hyfs4%8RwdQf+WD2 zbsLiSZIkDUoi(UbwqRiEt!xw0Cpd_@q*}})oWigwgpb9J8Zp+mT$v{C{mMAC8%B+2 z+!|DsRqTm`aWt(ss7P3z9a?!(LA68}SF5f4PND~^tVoHtYDLh7{&p>ECVaa#ye14R z0cpyxMvfRpo{2RH3Gr*A7hH0twiyGkMZB?)5srOZYc^Wnv34vdnZimsFmN*VbQrag zEzPA|7CR&=;w;jN%bSP?PR(_!q9aVWS^6s8L(#5wVJVv zU7hX&hJMys)ZAK?sbSeDy+~QzZse{JhnA+|2}dM{A-A>Anw;c?ZHhJWvLNW1Bv5alar2Vkx{?NKH#os68grlPV;?j3O1; zBCIzm`HW2#x}G2z_?q1-!?=}@rQvriKT$O&qvm;H0At&S^^4*}eMf82Gu0yY` z75RNf>YXrL3aj}YLs$ydJ6TGxuyPj0OPQwDELprTSSlTPc}PiEX;yLR<|-Z=?4ki& zcbC*N;9x6q8aYZ-Y bool: - """Returns if the given path exists and also matches the case on Windows. - - When finding files that can be imported, it is important for the cases to match because while - file os.path.exists("module.py") and os.path.exists("MODULE.py") both return True on Windows, - Python can only import using the case of the real file. - """ - result = os.path.exists(path) - if (sys.platform.startswith("win") or sys.platform == "darwin") and result: # pragma: no cover - directory, basename = os.path.split(path) - result = basename in os.listdir(directory) - return result diff --git a/env/lib/python3.8/site-packages/isort/wrap.py b/env/lib/python3.8/site-packages/isort/wrap.py deleted file mode 100644 index 11542fa0..00000000 --- a/env/lib/python3.8/site-packages/isort/wrap.py +++ /dev/null @@ -1,131 +0,0 @@ -import copy -import re -from typing import List, Optional, Sequence - -from .settings import DEFAULT_CONFIG, Config -from .wrap_modes import WrapModes as Modes -from .wrap_modes import formatter_from_string - - -def import_statement( - import_start: str, - from_imports: List[str], - comments: Sequence[str] = (), - line_separator: str = "\n", - config: Config = DEFAULT_CONFIG, - multi_line_output: Optional[Modes] = None, -) -> str: - """Returns a multi-line wrapped form of the provided from import statement.""" - formatter = formatter_from_string((multi_line_output or config.multi_line_output).name) - dynamic_indent = " " * (len(import_start) + 1) - indent = config.indent - line_length = config.wrap_length or config.line_length - statement = formatter( - statement=import_start, - imports=copy.copy(from_imports), - white_space=dynamic_indent, - indent=indent, - line_length=line_length, - comments=comments, - line_separator=line_separator, - comment_prefix=config.comment_prefix, - include_trailing_comma=config.include_trailing_comma, - remove_comments=config.ignore_comments, - ) - if config.balanced_wrapping: - lines = statement.split(line_separator) - line_count = len(lines) - if len(lines) > 1: - minimum_length = min(len(line) for line in lines[:-1]) - else: - minimum_length = 0 - new_import_statement = statement - while len(lines[-1]) < minimum_length and len(lines) == line_count and line_length > 10: - statement = new_import_statement - line_length -= 1 - new_import_statement = formatter( - statement=import_start, - imports=copy.copy(from_imports), - white_space=dynamic_indent, - indent=indent, - line_length=line_length, - comments=comments, - line_separator=line_separator, - comment_prefix=config.comment_prefix, - include_trailing_comma=config.include_trailing_comma, - remove_comments=config.ignore_comments, - ) - lines = new_import_statement.split(line_separator) - if statement.count(line_separator) == 0: - return _wrap_line(statement, line_separator, config) - return statement - - -def line(content: str, line_separator: str, config: Config = DEFAULT_CONFIG) -> str: - """Returns a line wrapped to the specified line-length, if possible.""" - wrap_mode = config.multi_line_output - if len(content) > config.line_length and wrap_mode != Modes.NOQA: # type: ignore - line_without_comment = content - comment = None - if "#" in content: - line_without_comment, comment = content.split("#", 1) - for splitter in ("import ", ".", "as "): - exp = r"\b" + re.escape(splitter) + r"\b" - if re.search(exp, line_without_comment) and not line_without_comment.strip().startswith( - splitter - ): - line_parts = re.split(exp, line_without_comment) - if comment and not (config.use_parentheses and "noqa" in comment): - _comma_maybe = ( - "," if (config.include_trailing_comma and config.use_parentheses) else "" - ) - line_parts[ - -1 - ] = f"{line_parts[-1].strip()}{_comma_maybe}{config.comment_prefix}{comment}" - next_line = [] - while (len(content) + 2) > ( - config.wrap_length or config.line_length - ) and line_parts: - next_line.append(line_parts.pop()) - content = splitter.join(line_parts) - if not content: - content = next_line.pop() - - cont_line = _wrap_line( - config.indent + splitter.join(next_line).lstrip(), line_separator, config - ) - if config.use_parentheses: - if splitter == "as ": - output = f"{content}{splitter}{cont_line.lstrip()}" - else: - _comma = "," if config.include_trailing_comma and not comment else "" - if wrap_mode in ( - Modes.VERTICAL_HANGING_INDENT, # type: ignore - Modes.VERTICAL_GRID_GROUPED, # type: ignore - ): - _separator = line_separator - else: - _separator = "" - _comment = "" - if comment and "noqa" in comment: - _comment = f"{config.comment_prefix}{comment}" - cont_line = cont_line.rstrip() - _comma = "," if config.include_trailing_comma else "" - output = ( - f"{content}{splitter}({_comment}" - f"{line_separator}{cont_line}{_comma}{_separator})" - ) - lines = output.split(line_separator) - if config.comment_prefix in lines[-1] and lines[-1].endswith(")"): - content, comment = lines[-1].split(config.comment_prefix, 1) - lines[-1] = content + ")" + config.comment_prefix + comment[:-1] - return line_separator.join(lines) - return f"{content}{splitter}\\{line_separator}{cont_line}" - elif len(content) > config.line_length and wrap_mode == Modes.NOQA: # type: ignore - if "# NOQA" not in content: - return f"{content}{config.comment_prefix} NOQA" - - return content - - -_wrap_line = line diff --git a/env/lib/python3.8/site-packages/isort/wrap_modes.py b/env/lib/python3.8/site-packages/isort/wrap_modes.py deleted file mode 100644 index 02b79306..00000000 --- a/env/lib/python3.8/site-packages/isort/wrap_modes.py +++ /dev/null @@ -1,325 +0,0 @@ -"""Defines all wrap modes that can be used when outputting formatted imports""" -import enum -from inspect import signature -from typing import Any, Callable, Dict, List - -import isort.comments - -_wrap_modes: Dict[str, Callable[[Any], str]] = {} - - -def from_string(value: str) -> "WrapModes": - return getattr(WrapModes, str(value), None) or WrapModes(int(value)) - - -def formatter_from_string(name: str): - return _wrap_modes.get(name.upper(), grid) - - -def _wrap_mode_interface( - statement: str, - imports: List[str], - white_space: str, - indent: str, - line_length: int, - comments: List[str], - line_separator: str, - comment_prefix: str, - include_trailing_comma: bool, - remove_comments: bool, -) -> str: - """Defines the common interface used by all wrap mode functions""" - return "" - - -def _wrap_mode(function): - """Registers an individual wrap mode. Function name and order are significant and used for - creating enum. - """ - _wrap_modes[function.__name__.upper()] = function - function.__signature__ = signature(_wrap_mode_interface) - function.__annotations__ = _wrap_mode_interface.__annotations__ - return function - - -@_wrap_mode -def grid(**interface): - if not interface["imports"]: - return "" - - interface["statement"] += "(" + interface["imports"].pop(0) - while interface["imports"]: - next_import = interface["imports"].pop(0) - next_statement = isort.comments.add_to_line( - interface["comments"], - interface["statement"] + ", " + next_import, - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - if ( - len(next_statement.split(interface["line_separator"])[-1]) + 1 - > interface["line_length"] - ): - lines = [f"{interface['white_space']}{next_import.split(' ')[0]}"] - for part in next_import.split(" ")[1:]: - new_line = f"{lines[-1]} {part}" - if len(new_line) + 1 > interface["line_length"]: - lines.append(f"{interface['white_space']}{part}") - else: - lines[-1] = new_line - next_import = interface["line_separator"].join(lines) - interface["statement"] = ( - isort.comments.add_to_line( - interface["comments"], - f"{interface['statement']},", - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + f"{interface['line_separator']}{next_import}" - ) - interface["comments"] = [] - else: - interface["statement"] += ", " + next_import - return interface["statement"] + ("," if interface["include_trailing_comma"] else "") + ")" - - -@_wrap_mode -def vertical(**interface): - if not interface["imports"]: - return "" - - first_import = ( - isort.comments.add_to_line( - interface["comments"], - interface["imports"].pop(0) + ",", - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + interface["line_separator"] - + interface["white_space"] - ) - - _imports = ("," + interface["line_separator"] + interface["white_space"]).join( - interface["imports"] - ) - _comma_maybe = "," if interface["include_trailing_comma"] else "" - return f"{interface['statement']}({first_import}{_imports}{_comma_maybe})" - - -def _hanging_indent_common(use_parentheses=False, **interface): - if not interface["imports"]: - return "" - line_length_limit = interface["line_length"] - (1 if use_parentheses else 3) - - def end_line(line): - if use_parentheses: - return line - if not line.endswith(" "): - line += " " - return line + "\\" - - if use_parentheses: - interface["statement"] += "(" - next_import = interface["imports"].pop(0) - next_statement = interface["statement"] + next_import - # Check for first import - if len(next_statement) > line_length_limit: - next_statement = ( - isort.comments.add_to_line( - interface["comments"], - end_line(interface["statement"]), - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + f"{interface['line_separator']}{interface['indent']}{next_import}" - ) - interface["comments"] = [] - interface["statement"] = next_statement - while interface["imports"]: - next_import = interface["imports"].pop(0) - next_statement = isort.comments.add_to_line( - interface["comments"], - interface["statement"] + ", " + next_import, - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - current_line = next_statement.split(interface["line_separator"])[-1] - if len(current_line) > line_length_limit: - next_statement = ( - isort.comments.add_to_line( - interface["comments"], - end_line(interface["statement"] + ","), - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + f"{interface['line_separator']}{interface['indent']}{next_import}" - ) - interface["comments"] = [] - interface["statement"] = next_statement - _comma_maybe = "," if interface["include_trailing_comma"] else "" - _close_parentheses_maybe = ")" if use_parentheses else "" - return interface["statement"] + _comma_maybe + _close_parentheses_maybe - - -@_wrap_mode -def hanging_indent(**interface): - return _hanging_indent_common(use_parentheses=False, **interface) - - -@_wrap_mode -def vertical_hanging_indent(**interface): - _line_with_comments = isort.comments.add_to_line( - interface["comments"], - "", - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - _imports = ("," + interface["line_separator"] + interface["indent"]).join(interface["imports"]) - _comma_maybe = "," if interface["include_trailing_comma"] else "" - return ( - f"{interface['statement']}({_line_with_comments}{interface['line_separator']}" - f"{interface['indent']}{_imports}{_comma_maybe}{interface['line_separator']})" - ) - - -def _vertical_grid_common(need_trailing_char: bool, **interface): - if not interface["imports"]: - return "" - - interface["statement"] += ( - isort.comments.add_to_line( - interface["comments"], - "(", - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + interface["line_separator"] - + interface["indent"] - + interface["imports"].pop(0) - ) - while interface["imports"]: - next_import = interface["imports"].pop(0) - next_statement = f"{interface['statement']}, {next_import}" - current_line_length = len(next_statement.split(interface["line_separator"])[-1]) - if interface["imports"] or need_trailing_char: - # If we have more interface["imports"] we need to account for a comma after this import - # We might also need to account for a closing ) we're going to add. - current_line_length += 1 - if current_line_length > interface["line_length"]: - next_statement = ( - f"{interface['statement']},{interface['line_separator']}" - f"{interface['indent']}{next_import}" - ) - interface["statement"] = next_statement - if interface["include_trailing_comma"]: - interface["statement"] += "," - return interface["statement"] - - -@_wrap_mode -def vertical_grid(**interface) -> str: - return _vertical_grid_common(need_trailing_char=True, **interface) + ")" - - -@_wrap_mode -def vertical_grid_grouped(**interface): - return ( - _vertical_grid_common(need_trailing_char=True, **interface) - + interface["line_separator"] - + ")" - ) - - -@_wrap_mode -def vertical_grid_grouped_no_comma(**interface): - return ( - _vertical_grid_common(need_trailing_char=False, **interface) - + interface["line_separator"] - + ")" - ) - - -@_wrap_mode -def noqa(**interface): - _imports = ", ".join(interface["imports"]) - retval = f"{interface['statement']}{_imports}" - comment_str = " ".join(interface["comments"]) - if interface["comments"]: - if ( - len(retval) + len(interface["comment_prefix"]) + 1 + len(comment_str) - <= interface["line_length"] - ): - return f"{retval}{interface['comment_prefix']} {comment_str}" - elif "NOQA" in interface["comments"]: - return f"{retval}{interface['comment_prefix']} {comment_str}" - else: - return f"{retval}{interface['comment_prefix']} NOQA {comment_str}" - else: - if len(retval) <= interface["line_length"]: - return retval - else: - return f"{retval}{interface['comment_prefix']} NOQA" - - -@_wrap_mode -def vertical_hanging_indent_bracket(**interface): - if not interface["imports"]: - return "" - statement = vertical_hanging_indent(**interface) - return f'{statement[:-1]}{interface["indent"]})' - - -@_wrap_mode -def vertical_prefix_from_module_import(**interface): - if not interface["imports"]: - return "" - - prefix_statement = interface["statement"] - output_statement = prefix_statement + interface["imports"].pop(0) - comments = interface["comments"] - - statement = output_statement - statement_with_comments = "" - for next_import in interface["imports"]: - statement = statement + ", " + next_import - statement_with_comments = isort.comments.add_to_line( - comments, - statement, - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - if ( - len(statement_with_comments.split(interface["line_separator"])[-1]) + 1 - > interface["line_length"] - ): - statement = ( - isort.comments.add_to_line( - comments, - output_statement, - removed=interface["remove_comments"], - comment_prefix=interface["comment_prefix"], - ) - + f"{interface['line_separator']}{prefix_statement}{next_import}" - ) - comments = [] - output_statement = statement - - if comments and statement_with_comments: - output_statement = statement_with_comments - return output_statement - - -@_wrap_mode -def hanging_indent_with_parentheses(**interface): - return _hanging_indent_common(use_parentheses=True, **interface) - - -@_wrap_mode -def backslash_grid(**interface): - interface["indent"] = interface["white_space"][:-1] - return _hanging_indent_common(use_parentheses=False, **interface) - - -WrapModes = enum.Enum( # type: ignore - "WrapModes", {wrap_mode: index for index, wrap_mode in enumerate(_wrap_modes.keys())} -) diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER b/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA b/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA deleted file mode 100644 index 6b4b8302..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA +++ /dev/null @@ -1,166 +0,0 @@ -Metadata-Version: 2.1 -Name: lazy-object-proxy -Version: 1.4.3 -Summary: A fast and thorough lazy object proxy. -Home-page: https://github.com/ionelmc/python-lazy-object-proxy -Author: Ionel Cristian Mărieș -Author-email: contact@ionelmc.ro -License: BSD-2-Clause -Project-URL: Documentation, https://python-lazy-object-proxy.readthedocs.io/ -Project-URL: Changelog, https://python-lazy-object-proxy.readthedocs.io/en/latest/changelog.html -Project-URL: Issue Tracker, https://github.com/ionelmc/python-lazy-object-proxy/issues -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: Unix -Classifier: Operating System :: POSIX -Classifier: Operating System :: Microsoft :: Windows -Classifier: Programming Language :: Python -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 :: 3.8 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Utilities -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* - -======== -Overview -======== - - - -A fast and thorough lazy object proxy. - -* Free software: BSD 2-Clause License - -Note that this is based on `wrapt`_'s ObjectProxy with one big change: it calls a function the first time the proxy object is -used, while `wrapt.ObjectProxy` just forwards the method calls to the target object. - -In other words, you use `lazy-object-proxy` when you only have the object way later and you use `wrapt.ObjectProxy` when you -want to override few methods (by subclassing) and forward everything else to the target object. - -Example:: - - import lazy_object_proxy - - def expensive_func(): - from time import sleep - print('starting calculation') - # just as example for a very slow computation - sleep(2) - print('finished calculation') - # return the result of the calculation - return 10 - - obj = lazy_object_proxy.Proxy(expensive_func) - # function is called only when object is actually used - print(obj) # now expensive_func is called - - print(obj) # the result without calling the expensive_func - -Installation -============ - -:: - - pip install lazy-object-proxy - -Documentation -============= - -https://python-lazy-object-proxy.readthedocs.io/ - -Development -=========== - -To run the all tests run:: - - tox - -Acknowledgements -================ - -This project is based on some code from `wrapt`_ as you can see in the git history. - -.. _wrapt: https://github.com/GrahamDumpleton/wrapt - - -Changelog -========= - -1.4.3 (2019-10-26) ------------------- - -* Added binary wheels for Python 3.8. -* Fixed license metadata. - -1.4.2 (2019-08-22) ------------------- - -* Included a ``pyproject.toml`` to allow users install the sdist with old python/setuptools, as the - setuptools-scm dep will be fetched by pip instead of setuptools. - Fixes `#30 `_. - -1.4.1 (2019-05-10) ------------------- - -* Fixed wheels being built with ``-coverage`` cflags. No more issues about bogus ``cext.gcda`` files. -* Removed useless C file from wheels. -* Changed ``setup.py`` to use setuptools-scm. - -1.4.0 (2019-05-05) ------------------- - -* Fixed ``__mod__`` for the slots backend. Contributed by Ran Benita in - `#28 `_. -* Dropped support for Python 2.6 and 3.3. Contributed by "hugovk" in - `#24 `_. - -1.3.1 (2017-05-05) ------------------- - -* Fix broken release (``sdist`` had a broken ``MANIFEST.in``). - -1.3.0 (2017-05-02) ------------------- - -* Speed up arithmetic operations involving ``cext.Proxy`` subclasses. - -1.2.2 (2016-04-14) ------------------- - -* Added `manylinux `_ wheels. -* Minor cleanup in readme. - -1.2.1 (2015-08-18) ------------------- - -* Fix a memory leak (the wrapped object would get bogus references). Contributed by Astrum Kuo in - `#10 `_. - -1.2.0 (2015-07-06) ------------------- - -* Don't instantiate the object when __repr__ is called. This aids with debugging (allows one to see exactly in - what state the proxy is). - -1.1.0 (2015-07-05) ------------------- - -* Added support for pickling. The pickled value is going to be the wrapped object *without* any Proxy container. -* Fixed a memory management issue in the C extension (reference cycles weren't garbage collected due to improper - handling in the C extension). Contributed by Alvin Chow in - `#8 `_. - -1.0.2 (2015-04-11) ------------------------------------------ - -* First release on PyPI. - - diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD b/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD deleted file mode 100644 index edc1035e..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD +++ /dev/null @@ -1,18 +0,0 @@ -lazy_object_proxy-1.4.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -lazy_object_proxy-1.4.3.dist-info/METADATA,sha256=Y2X63wcFbQT4yI3zKpRFwfpA_TCpB6U79MPmRGCMJT0,5088 -lazy_object_proxy-1.4.3.dist-info/RECORD,, -lazy_object_proxy-1.4.3.dist-info/WHEEL,sha256=VEyGcIFAmk_1KbI6gaZGw_mMiT-pdGweASQLX-DzYaY,108 -lazy_object_proxy-1.4.3.dist-info/top_level.txt,sha256=UNH-FQB-j_8bYqPz3gD90kHvaC42TQqY0thHSnbaa0k,18 -lazy_object_proxy/__init__.py,sha256=pMqxzToF24DuzOltm-Q8nZ3jNDXOaSQcJmiNArdUrlU,410 -lazy_object_proxy/__pycache__/__init__.cpython-38.pyc,, -lazy_object_proxy/__pycache__/_version.cpython-38.pyc,, -lazy_object_proxy/__pycache__/compat.cpython-38.pyc,, -lazy_object_proxy/__pycache__/simple.cpython-38.pyc,, -lazy_object_proxy/__pycache__/slots.cpython-38.pyc,, -lazy_object_proxy/__pycache__/utils.cpython-38.pyc,, -lazy_object_proxy/_version.py,sha256=ALahZZsa-Z4ZoXe2iDIs4ajidCOW695W5leOWijWYEc,116 -lazy_object_proxy/cext.cpython-38-x86_64-linux-gnu.so,sha256=-2QmXTob8M7FEpnLb1sI3f0UR1Q_YhV1z1EupaBk3F0,170352 -lazy_object_proxy/compat.py,sha256=DY3HbKwbrbeKY6tkXRNRLJ1go6HJb8HUwWqyw3T5g_g,196 -lazy_object_proxy/simple.py,sha256=guacy8_QbJeBs7vXpPPVoDVkDNXOZ86xyS1dtAeKvOs,8216 -lazy_object_proxy/slots.py,sha256=9DilWUINScpZN26NwmRtscTtaqaEwtCfIoriLq5Nz24,11359 -lazy_object_proxy/utils.py,sha256=x4XTrtlp_mDTWO_EOq_ILIOv2Qol8RLMnRm5M8l3OfU,291 diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL b/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL deleted file mode 100644 index ae40efdd..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.31.1) -Root-Is-Purelib: false -Tag: cp38-cp38-manylinux1_x86_64 - diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt b/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt deleted file mode 100644 index bdf032e9..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -lazy_object_proxy diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/__init__.py b/env/lib/python3.8/site-packages/lazy_object_proxy/__init__.py deleted file mode 100644 index e9a9a763..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -try: - import copy_reg as copyreg -except ImportError: - import copyreg - -from .utils import identity - -copyreg.constructor(identity) - -try: - from .cext import Proxy - from .cext import identity -except ImportError: - from .slots import Proxy -else: - copyreg.constructor(identity) - -try: - from ._version import version as __version__ -except ImportError: - __version__ = '1.4.3' - -__all__ = "Proxy", diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 99530aa0abb51f36da67b6ab2a167acf197f42cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 571 zcmYk2F;Cnu6vypca!GSJggP-WF!lz{LNG8O#KOQ*RYDcu#R|#Oor_~fwhxgL-=k6| zI(F;au^%IAC%ys`&qpd@D^LGt|NlQd=j(Ku6I{pN|B4@!kbj|hzcOsj@N<8#tc#k| zR1r?Eh~A9}M0dIUL`m428_MYo(a|-jqk5!9P0V9TfIcM<|D=?xckw({<0j=PCW2@D z=0V=xz+WQuv)_1Q^d>Xm}i@PphQmWUQ~i*7|llt)2tWA|~RgUX{yVq>%9^GH^c-DP(ZOfKRXyoSd}>k;g%e2Rqw zGsD0P?;Ymz86&K&ckaj^pYRWl!j@=#lAIk`?(JDH>L-h68O6K68>TH9E0nx3GosE{ zUKNz8MzEL}bV?!=!f}IIS!kpHon)@WI+3A8Lwi8kLM2krohy}$qZL@;Fr?l&DbPZd h^c`2}2{XsFQI`(*?`)*I!C%)ZZz|l3>47Jay#b>EJyHMw diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/compat.cpython-38.pyc b/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/compat.cpython-38.pyc deleted file mode 100644 index b2ebee720a86e4db57e7188e40a83465e13aac3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 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 ui;r?a<@BG5Y3&7j!W6*k(Ol3vgJn>3EA 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 diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/utils.cpython-38.pyc b/env/lib/python3.8/site-packages/lazy_object_proxy/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index bacc626fb9d003dcf53fff33ef0835813095fbeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 811 zcmZWny>in)5Z=?tjtB{qq@bfgMSKNKiVTw(3OY9)8aFq}-Nu$9OX5!QAdjfXJJ3Rz z*WfYK@)lI=p5x#NJF~0Z)Bb$>-F-SeJqD7C@4xgL0q~oHLy0N4BK5DySg_&_=I{}0 zWaS-LiQ=1_M>d{8IxrWZ-8IXqd^fpJK5y`x@@}&QdR1iGPSXf9 zjjmnwrBiK_7k*NALy}u8o4n~5n`a0h+=#4U_fYuX6=_%;VJ!TDElnB?vB%=Z9ns-Gb{vy8 zBwFVsv7*NmJ>cG+JsCUMCmBgud*OPH!~D18^t8%t;!gNRdiX){PZ7gc*^3n+Tfr*2 zgkJ8^$$*Ce*qr#(?3LLXwN7J~P&>!X2WbjFj5b-(;#2HLS}%|)pHZIY3J{5i#hKW? z`hS6tIZa3IId?tQdR^JJplQR2)}Py~*v)p_%)Ma4+#VQS*D*_ctKsD(B9Y-_n#yq3 Y!+7^N!r?(_=(MBzayRz<<1'.format( - type(self).__name__, id(self), - self.__wrapped__, id(self.__wrapped__), - self.__factory__ - ) - else: - return '<{} at 0x{:x} with factory {!r}>'.format( - type(self).__name__, id(self), - self.__factory__ - ) - - __reversed__ = make_proxy_method(reversed) - - if PY3: - __round__ = make_proxy_method(round) - - __lt__ = make_proxy_method(operator.lt) - __le__ = make_proxy_method(operator.le) - __eq__ = make_proxy_method(operator.eq) - __ne__ = make_proxy_method(operator.ne) - __gt__ = make_proxy_method(operator.gt) - __ge__ = make_proxy_method(operator.ge) - __hash__ = make_proxy_method(hash) - __nonzero__ = make_proxy_method(bool) - __bool__ = make_proxy_method(bool) - - def __setattr__(self, name, value): - if hasattr(type(self), name): - self.__dict__[name] = value - else: - setattr(self.__wrapped__, name, value) - - def __getattr__(self, name): - if name in ('__wrapped__', '__factory__'): - raise AttributeError(name) - else: - return getattr(self.__wrapped__, name) - - def __delattr__(self, name): - if hasattr(type(self), name): - del self.__dict__[name] - else: - delattr(self.__wrapped__, name) - - __add__ = make_proxy_method(operator.add) - __sub__ = make_proxy_method(operator.sub) - __mul__ = make_proxy_method(operator.mul) - __div__ = make_proxy_method(operator.div if PY2 else operator.truediv) - __truediv__ = make_proxy_method(operator.truediv) - __floordiv__ = make_proxy_method(operator.floordiv) - __mod__ = make_proxy_method(operator.mod) - __divmod__ = make_proxy_method(divmod) - __pow__ = make_proxy_method(pow) - __lshift__ = make_proxy_method(operator.lshift) - __rshift__ = make_proxy_method(operator.rshift) - __and__ = make_proxy_method(operator.and_) - __xor__ = make_proxy_method(operator.xor) - __or__ = make_proxy_method(operator.or_) - - 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__ - - __iadd__ = make_proxy_method(operator.iadd) - __isub__ = make_proxy_method(operator.isub) - __imul__ = make_proxy_method(operator.imul) - __idiv__ = make_proxy_method(operator.idiv if PY2 else operator.itruediv) - __itruediv__ = make_proxy_method(operator.itruediv) - __ifloordiv__ = make_proxy_method(operator.ifloordiv) - __imod__ = make_proxy_method(operator.imod) - __ipow__ = make_proxy_method(operator.ipow) - __ilshift__ = make_proxy_method(operator.ilshift) - __irshift__ = make_proxy_method(operator.irshift) - __iand__ = make_proxy_method(operator.iand) - __ixor__ = make_proxy_method(operator.ixor) - __ior__ = make_proxy_method(operator.ior) - __neg__ = make_proxy_method(operator.neg) - __pos__ = make_proxy_method(operator.pos) - __abs__ = make_proxy_method(operator.abs) - __invert__ = make_proxy_method(operator.invert) - - __int__ = make_proxy_method(int) - - if PY2: - __long__ = make_proxy_method(long) # noqa - - __float__ = make_proxy_method(float) - __oct__ = make_proxy_method(oct) - __hex__ = make_proxy_method(hex) - __index__ = make_proxy_method(operator.index) - __len__ = make_proxy_method(len) - __contains__ = make_proxy_method(operator.contains) - __getitem__ = make_proxy_method(operator.getitem) - __setitem__ = make_proxy_method(operator.setitem) - __delitem__ = make_proxy_method(operator.delitem) - - if PY2: - __getslice__ = make_proxy_method(operator.getslice) - __setslice__ = make_proxy_method(operator.setslice) - __delslice__ = make_proxy_method(operator.delslice) - - def __enter__(self): - return self.__wrapped__.__enter__() - - def __exit__(self, *args, **kwargs): - return self.__wrapped__.__exit__(*args, **kwargs) - - __iter__ = make_proxy_method(iter) - - def __call__(self, *args, **kwargs): - return self.__wrapped__(*args, **kwargs) - - def __reduce__(self): - return identity, (self.__wrapped__,) - - def __reduce_ex__(self, protocol): - return identity, (self.__wrapped__,) diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/slots.py b/env/lib/python3.8/site-packages/lazy_object_proxy/slots.py deleted file mode 100644 index efb08db9..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy/slots.py +++ /dev/null @@ -1,414 +0,0 @@ -import operator - -from .compat import PY2 -from .compat import PY3 -from .compat import with_metaclass -from .utils import identity - - -class _ProxyMethods(object): - # We use properties to override the values of __module__ and - # __doc__. If we add these in ObjectProxy, the derived class - # __dict__ will still be setup to have string variants of these - # attributes and the rules of descriptors means that they appear to - # take precedence over the properties in the base class. To avoid - # that, we copy the properties into the derived class type itself - # via a meta class. In that way the properties will always take - # precedence. - - @property - def __module__(self): - return self.__wrapped__.__module__ - - @__module__.setter - def __module__(self, value): - self.__wrapped__.__module__ = value - - @property - def __doc__(self): - return self.__wrapped__.__doc__ - - @__doc__.setter - def __doc__(self, value): - self.__wrapped__.__doc__ = value - - # We similar use a property for __dict__. We need __dict__ to be - # explicit to ensure that vars() works as expected. - - @property - def __dict__(self): - return self.__wrapped__.__dict__ - - # Need to also propagate the special __weakref__ attribute for case - # where decorating classes which will define this. If do not define - # it and use a function like inspect.getmembers() on a decorator - # class it will fail. This can't be in the derived classes. - - @property - def __weakref__(self): - return self.__wrapped__.__weakref__ - - -class _ProxyMetaType(type): - def __new__(cls, name, bases, dictionary): - # Copy our special properties into the class so that they - # always take precedence over attributes of the same name added - # during construction of a derived class. This is to save - # duplicating the implementation for them in all derived classes. - - dictionary.update(vars(_ProxyMethods)) - - return type.__new__(cls, name, bases, dictionary) - - -class Proxy(with_metaclass(_ProxyMetaType)): - """ - A proxy implementation in pure Python, using slots. You can subclass this to add - local methods or attributes, or enable __dict__. - - The most important internals: - - * ``__factory__`` is the callback that "materializes" the object we proxy to. - * ``__target__`` will contain the object we proxy to, once it's "materialized". - * ``__wrapped__`` is a property that does either: - - * return ``__target__`` if it's set. - * calls ``__factory__``, saves result to ``__target__`` and returns said result. - """ - - __slots__ = '__target__', '__factory__' - - def __init__(self, factory): - object.__setattr__(self, '__factory__', factory) - - @property - def __wrapped__(self, __getattr__=object.__getattribute__, __setattr__=object.__setattr__, - __delattr__=object.__delattr__): - try: - return __getattr__(self, '__target__') - except AttributeError: - try: - factory = __getattr__(self, '__factory__') - except AttributeError: - raise ValueError("Proxy hasn't been initiated: __factory__ is missing.") - target = factory() - __setattr__(self, '__target__', target) - return target - - @__wrapped__.deleter - def __wrapped__(self, __delattr__=object.__delattr__): - __delattr__(self, '__target__') - - @__wrapped__.setter - def __wrapped__(self, target, __setattr__=object.__setattr__): - __setattr__(self, '__target__', target) - - @property - def __name__(self): - return self.__wrapped__.__name__ - - @__name__.setter - def __name__(self, value): - self.__wrapped__.__name__ = value - - @property - def __class__(self): - return self.__wrapped__.__class__ - - @__class__.setter # noqa - def __class__(self, value): - self.__wrapped__.__class__ = value - - @property - def __annotations__(self): - return self.__wrapped__.__anotations__ - - @__annotations__.setter - def __annotations__(self, value): - self.__wrapped__.__annotations__ = value - - def __dir__(self): - return dir(self.__wrapped__) - - def __str__(self): - return str(self.__wrapped__) - - if PY3: - def __bytes__(self): - return bytes(self.__wrapped__) - - def __repr__(self, __getattr__=object.__getattribute__): - try: - target = __getattr__(self, '__target__') - except AttributeError: - return '<{} at 0x{:x} with factory {!r}>'.format( - type(self).__name__, id(self), - self.__factory__ - ) - else: - return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format( - type(self).__name__, id(self), - target, id(target), - self.__factory__ - ) - - 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, __setattr__=object.__setattr__): - if hasattr(type(self), name): - __setattr__(self, name, value) - else: - setattr(self.__wrapped__, name, value) - - def __getattr__(self, name): - if name in ('__wrapped__', '__factory__'): - raise AttributeError(name) - else: - return getattr(self.__wrapped__, name) - - def __delattr__(self, name, __delattr__=object.__delattr__): - if hasattr(type(self), name): - __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__) - - if PY2: - def __long__(self): - return long(self.__wrapped__) # noqa - - def __float__(self): - return float(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 __call__(self, *args, **kwargs): - return self.__wrapped__(*args, **kwargs) - - def __reduce__(self): - return identity, (self.__wrapped__,) - - def __reduce_ex__(self, protocol): - return identity, (self.__wrapped__,) diff --git a/env/lib/python3.8/site-packages/lazy_object_proxy/utils.py b/env/lib/python3.8/site-packages/lazy_object_proxy/utils.py deleted file mode 100644 index ceb3050f..00000000 --- a/env/lib/python3.8/site-packages/lazy_object_proxy/utils.py +++ /dev/null @@ -1,13 +0,0 @@ -def identity(obj): - return obj - - -class cached_property(object): - def __init__(self, func): - self.func = func - - def __get__(self, obj, cls): - if obj is None: - return self - value = obj.__dict__[self.func.__name__] = self.func(obj) - return value diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst deleted file mode 100644 index de610685..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst +++ /dev/null @@ -1,152 +0,0 @@ -McCabe complexity checker -========================= - -Ned's script to check McCabe complexity. - -This module provides a plugin for ``flake8``, the Python code checker. - - -Installation ------------- - -You can install, upgrade, uninstall ``mccabe`` with these commands:: - - $ pip install mccabe - $ pip install --upgrade mccabe - $ pip uninstall mccabe - - -Standalone script ------------------ - -The complexity checker can be used directly:: - - $ python -m mccabe --min 5 mccabe.py - ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) - ("71:1: 'PathGraph.to_dot'", 5) - ("245:1: 'McCabeChecker.run'", 5) - ("283:1: 'main'", 7) - ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) - ("257:1: 'get_code_complexity'", 5) - - -Plugin for Flake8 ------------------ - -When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is -available in ``flake8``:: - - $ flake8 --version - 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) - -By default the plugin is disabled. Use the ``--max-complexity`` switch to -enable it. It will emit a warning if the McCabe complexity of a function is -higher that the value:: - - $ flake8 --max-complexity 10 coolproject - ... - coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) - -This feature is quite useful to detect over-complex code. According to McCabe, -anything that goes beyond 10 is too complex. - - -Links ------ - -* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality - -* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. - -* Ned Batchelder's script: - http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html - - -Changes -------- - -0.6.1 - 2017-01-26 -`````````````````` - -* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature - for ``ASTVisitor`` - -0.6.0 - 2017-01-23 -`````````````````` - -* Add support for Python 3.6 - -* Fix handling for missing statement types - -0.5.3 - 2016-12-14 -`````````````````` - -* Report actual column number of violation instead of the start of the line - -0.5.2 - 2016-07-31 -`````````````````` - -* When opening files ourselves, make sure we always name the file variable - -0.5.1 - 2016-07-28 -`````````````````` - -* Set default maximum complexity to -1 on the class itself - -0.5.0 - 2016-05-30 -`````````````````` - -* PyCon 2016 PDX release - -* Add support for Flake8 3.0 - -0.4.0 - 2016-01-27 -`````````````````` - -* Stop testing on Python 3.2 - -* Add support for async/await keywords on Python 3.5 from PEP 0492 - -0.3.1 - 2015-06-14 -`````````````````` - -* Include ``test_mccabe.py`` in releases. - -* Always coerce the ``max_complexity`` value from Flake8's entry-point to an - integer. - -0.3 - 2014-12-17 -```````````````` - -* Computation was wrong: the mccabe complexity starts at 1, not 2. - -* The ``max-complexity`` value is now inclusive. E.g.: if the - value is 10 and the reported complexity is 10, then it passes. - -* Add tests. - - -0.2.1 - 2013-04-03 -`````````````````` - -* Do not require ``setuptools`` in setup.py. It works around an issue - with ``pip`` and Python 3. - - -0.2 - 2013-02-22 -```````````````` - -* Rename project to ``mccabe``. - -* Provide ``flake8.extension`` setuptools entry point. - -* Read ``max-complexity`` from the configuration file. - -* Rename argument ``min_complexity`` to ``threshold``. - - -0.1 - 2013-02-11 -```````````````` -* First release - - diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/INSTALLER b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/METADATA b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/METADATA deleted file mode 100644 index f22645f3..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/METADATA +++ /dev/null @@ -1,178 +0,0 @@ -Metadata-Version: 2.0 -Name: mccabe -Version: 0.6.1 -Summary: McCabe checker, plugin for flake8 -Home-page: https://github.com/pycqa/mccabe -Author: Ian Cordasco -Author-email: graffatcolmingov@gmail.com -License: Expat license -Keywords: flake8 mccabe -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Software Development :: Quality Assurance - -McCabe complexity checker -========================= - -Ned's script to check McCabe complexity. - -This module provides a plugin for ``flake8``, the Python code checker. - - -Installation ------------- - -You can install, upgrade, uninstall ``mccabe`` with these commands:: - - $ pip install mccabe - $ pip install --upgrade mccabe - $ pip uninstall mccabe - - -Standalone script ------------------ - -The complexity checker can be used directly:: - - $ python -m mccabe --min 5 mccabe.py - ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) - ("71:1: 'PathGraph.to_dot'", 5) - ("245:1: 'McCabeChecker.run'", 5) - ("283:1: 'main'", 7) - ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) - ("257:1: 'get_code_complexity'", 5) - - -Plugin for Flake8 ------------------ - -When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is -available in ``flake8``:: - - $ flake8 --version - 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) - -By default the plugin is disabled. Use the ``--max-complexity`` switch to -enable it. It will emit a warning if the McCabe complexity of a function is -higher that the value:: - - $ flake8 --max-complexity 10 coolproject - ... - coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) - -This feature is quite useful to detect over-complex code. According to McCabe, -anything that goes beyond 10 is too complex. - - -Links ------ - -* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality - -* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. - -* Ned Batchelder's script: - http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html - - -Changes -------- - -0.6.1 - 2017-01-26 -`````````````````` - -* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature - for ``ASTVisitor`` - -0.6.0 - 2017-01-23 -`````````````````` - -* Add support for Python 3.6 - -* Fix handling for missing statement types - -0.5.3 - 2016-12-14 -`````````````````` - -* Report actual column number of violation instead of the start of the line - -0.5.2 - 2016-07-31 -`````````````````` - -* When opening files ourselves, make sure we always name the file variable - -0.5.1 - 2016-07-28 -`````````````````` - -* Set default maximum complexity to -1 on the class itself - -0.5.0 - 2016-05-30 -`````````````````` - -* PyCon 2016 PDX release - -* Add support for Flake8 3.0 - -0.4.0 - 2016-01-27 -`````````````````` - -* Stop testing on Python 3.2 - -* Add support for async/await keywords on Python 3.5 from PEP 0492 - -0.3.1 - 2015-06-14 -`````````````````` - -* Include ``test_mccabe.py`` in releases. - -* Always coerce the ``max_complexity`` value from Flake8's entry-point to an - integer. - -0.3 - 2014-12-17 -```````````````` - -* Computation was wrong: the mccabe complexity starts at 1, not 2. - -* The ``max-complexity`` value is now inclusive. E.g.: if the - value is 10 and the reported complexity is 10, then it passes. - -* Add tests. - - -0.2.1 - 2013-04-03 -`````````````````` - -* Do not require ``setuptools`` in setup.py. It works around an issue - with ``pip`` and Python 3. - - -0.2 - 2013-02-22 -```````````````` - -* Rename project to ``mccabe``. - -* Provide ``flake8.extension`` setuptools entry point. - -* Read ``max-complexity`` from the configuration file. - -* Rename argument ``min_complexity`` to ``threshold``. - - -0.1 - 2013-02-11 -```````````````` -* First release - - diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/RECORD b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/RECORD deleted file mode 100644 index df6a393d..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/RECORD +++ /dev/null @@ -1,10 +0,0 @@ -__pycache__/mccabe.cpython-38.pyc,, -mccabe-0.6.1.dist-info/DESCRIPTION.rst,sha256=lGHJ-Y3IviuP3DRqLL_TXPUr3wJ2GZ8XJkAV6ve3O58,3302 -mccabe-0.6.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -mccabe-0.6.1.dist-info/METADATA,sha256=jawnTfTVrlzBSmeI-cTXSRIwIlijODtZdj-padBqIv0,4324 -mccabe-0.6.1.dist-info/RECORD,, -mccabe-0.6.1.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 -mccabe-0.6.1.dist-info/entry_points.txt,sha256=N2NH182GXTUyTm8r8XMgadb9C-CRa5dUr1k8OC91uGE,47 -mccabe-0.6.1.dist-info/metadata.json,sha256=e508OR4t6_G7h7eO2C6NHlHQqVpPZZH1_DlAPrVECYM,1218 -mccabe-0.6.1.dist-info/top_level.txt,sha256=21cXuqZE-lpcfAqqANvX9EjI1ED1p8zcViv064u3RKA,7 -mccabe.py,sha256=XPMywdQshG_5nSjckb-OzNqnCQuXQvy3FTClspKwGQA,10693 diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/WHEEL b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/WHEEL deleted file mode 100644 index 8b6dd1b5..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.29.0) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/entry_points.txt deleted file mode 100644 index cc6645bd..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[flake8.extension] -C90 = mccabe:McCabeChecker - diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/metadata.json b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/metadata.json deleted file mode 100644 index ae04d8fa..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Quality Assurance"], "extensions": {"python.details": {"contacts": [{"email": "graffatcolmingov@gmail.com", "name": "Ian Cordasco", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/pycqa/mccabe"}}, "python.exports": {"flake8.extension": {"C90": "mccabe:McCabeChecker"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["flake8", "mccabe"], "license": "Expat license", "metadata_version": "2.0", "name": "mccabe", "summary": "McCabe checker, plugin for flake8", "test_requires": [{"requires": ["pytest"]}], "version": "0.6.1"} \ No newline at end of file diff --git a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/top_level.txt b/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/top_level.txt deleted file mode 100644 index 8831b36b..00000000 --- a/env/lib/python3.8/site-packages/mccabe-0.6.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -mccabe diff --git a/env/lib/python3.8/site-packages/mccabe.py b/env/lib/python3.8/site-packages/mccabe.py deleted file mode 100644 index c0cda756..00000000 --- a/env/lib/python3.8/site-packages/mccabe.py +++ /dev/null @@ -1,347 +0,0 @@ -""" Meager code path measurement tool. - Ned Batchelder - http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html - MIT License. -""" -from __future__ import with_statement - -import optparse -import sys -import tokenize - -from collections import defaultdict -try: - import ast - from ast import iter_child_nodes -except ImportError: # Python 2.5 - from flake8.util import ast, iter_child_nodes - -__version__ = '0.6.1' - - -class ASTVisitor(object): - """Performs a depth-first walk of the AST.""" - - def __init__(self): - self.node = None - self._cache = {} - - def default(self, node, *args): - for child in iter_child_nodes(node): - self.dispatch(child, *args) - - def dispatch(self, node, *args): - self.node = node - klass = node.__class__ - meth = self._cache.get(klass) - if meth is None: - className = klass.__name__ - meth = getattr(self.visitor, 'visit' + className, self.default) - self._cache[klass] = meth - return meth(node, *args) - - def preorder(self, tree, visitor, *args): - """Do preorder walk of tree using visitor""" - self.visitor = visitor - visitor.visit = self.dispatch - self.dispatch(tree, *args) # XXX *args make sense? - - -class PathNode(object): - def __init__(self, name, look="circle"): - self.name = name - self.look = look - - def to_dot(self): - print('node [shape=%s,label="%s"] %d;' % ( - self.look, self.name, self.dot_id())) - - def dot_id(self): - return id(self) - - -class PathGraph(object): - def __init__(self, name, entity, lineno, column=0): - self.name = name - self.entity = entity - self.lineno = lineno - self.column = column - self.nodes = defaultdict(list) - - def connect(self, n1, n2): - self.nodes[n1].append(n2) - # Ensure that the destination node is always counted. - self.nodes[n2] = [] - - def to_dot(self): - print('subgraph {') - for node in self.nodes: - node.to_dot() - for node, nexts in self.nodes.items(): - for next in nexts: - print('%s -- %s;' % (node.dot_id(), next.dot_id())) - print('}') - - def complexity(self): - """ Return the McCabe complexity for the graph. - V-E+2 - """ - num_edges = sum([len(n) for n in self.nodes.values()]) - num_nodes = len(self.nodes) - return num_edges - num_nodes + 2 - - -class PathGraphingAstVisitor(ASTVisitor): - """ A visitor for a parsed Abstract Syntax Tree which finds executable - statements. - """ - - def __init__(self): - super(PathGraphingAstVisitor, self).__init__() - self.classname = "" - self.graphs = {} - self.reset() - - def reset(self): - self.graph = None - self.tail = None - - def dispatch_list(self, node_list): - for node in node_list: - self.dispatch(node) - - def visitFunctionDef(self, node): - - if self.classname: - entity = '%s%s' % (self.classname, node.name) - else: - entity = node.name - - name = '%d:%d: %r' % (node.lineno, node.col_offset, entity) - - if self.graph is not None: - # closure - pathnode = self.appendPathNode(name) - self.tail = pathnode - self.dispatch_list(node.body) - bottom = PathNode("", look='point') - self.graph.connect(self.tail, bottom) - self.graph.connect(pathnode, bottom) - self.tail = bottom - else: - self.graph = PathGraph(name, entity, node.lineno, node.col_offset) - pathnode = PathNode(name) - self.tail = pathnode - self.dispatch_list(node.body) - self.graphs["%s%s" % (self.classname, node.name)] = self.graph - self.reset() - - visitAsyncFunctionDef = visitFunctionDef - - def visitClassDef(self, node): - old_classname = self.classname - self.classname += node.name + "." - self.dispatch_list(node.body) - self.classname = old_classname - - def appendPathNode(self, name): - if not self.tail: - return - pathnode = PathNode(name) - self.graph.connect(self.tail, pathnode) - self.tail = pathnode - return pathnode - - def visitSimpleStatement(self, node): - if node.lineno is None: - lineno = 0 - else: - lineno = node.lineno - name = "Stmt %d" % lineno - self.appendPathNode(name) - - def default(self, node, *args): - if isinstance(node, ast.stmt): - self.visitSimpleStatement(node) - else: - super(PathGraphingAstVisitor, self).default(node, *args) - - def visitLoop(self, node): - name = "Loop %d" % node.lineno - self._subgraph(node, name) - - visitAsyncFor = visitFor = visitWhile = visitLoop - - def visitIf(self, node): - name = "If %d" % node.lineno - self._subgraph(node, name) - - def _subgraph(self, node, name, extra_blocks=()): - """create the subgraphs representing any `if` and `for` statements""" - if self.graph is None: - # global loop - self.graph = PathGraph(name, name, node.lineno, node.col_offset) - pathnode = PathNode(name) - self._subgraph_parse(node, pathnode, extra_blocks) - self.graphs["%s%s" % (self.classname, name)] = self.graph - self.reset() - else: - pathnode = self.appendPathNode(name) - self._subgraph_parse(node, pathnode, extra_blocks) - - def _subgraph_parse(self, node, pathnode, extra_blocks): - """parse the body and any `else` block of `if` and `for` statements""" - loose_ends = [] - self.tail = pathnode - self.dispatch_list(node.body) - loose_ends.append(self.tail) - for extra in extra_blocks: - self.tail = pathnode - self.dispatch_list(extra.body) - loose_ends.append(self.tail) - if node.orelse: - self.tail = pathnode - self.dispatch_list(node.orelse) - loose_ends.append(self.tail) - else: - loose_ends.append(pathnode) - if pathnode: - bottom = PathNode("", look='point') - for le in loose_ends: - self.graph.connect(le, bottom) - self.tail = bottom - - def visitTryExcept(self, node): - name = "TryExcept %d" % node.lineno - self._subgraph(node, name, extra_blocks=node.handlers) - - visitTry = visitTryExcept - - def visitWith(self, node): - name = "With %d" % node.lineno - self.appendPathNode(name) - self.dispatch_list(node.body) - - visitAsyncWith = visitWith - - -class McCabeChecker(object): - """McCabe cyclomatic complexity checker.""" - name = 'mccabe' - version = __version__ - _code = 'C901' - _error_tmpl = "C901 %r is too complex (%d)" - max_complexity = -1 - - def __init__(self, tree, filename): - self.tree = tree - - @classmethod - def add_options(cls, parser): - flag = '--max-complexity' - kwargs = { - 'default': -1, - 'action': 'store', - 'type': 'int', - 'help': 'McCabe complexity threshold', - 'parse_from_config': 'True', - } - config_opts = getattr(parser, 'config_options', None) - if isinstance(config_opts, list): - # Flake8 2.x - kwargs.pop('parse_from_config') - parser.add_option(flag, **kwargs) - parser.config_options.append('max-complexity') - else: - parser.add_option(flag, **kwargs) - - @classmethod - def parse_options(cls, options): - cls.max_complexity = int(options.max_complexity) - - def run(self): - if self.max_complexity < 0: - return - visitor = PathGraphingAstVisitor() - visitor.preorder(self.tree, visitor) - for graph in visitor.graphs.values(): - if graph.complexity() > self.max_complexity: - text = self._error_tmpl % (graph.entity, graph.complexity()) - yield graph.lineno, graph.column, text, type(self) - - -def get_code_complexity(code, threshold=7, filename='stdin'): - try: - tree = compile(code, filename, "exec", ast.PyCF_ONLY_AST) - except SyntaxError: - e = sys.exc_info()[1] - sys.stderr.write("Unable to parse %s: %s\n" % (filename, e)) - return 0 - - complx = [] - McCabeChecker.max_complexity = threshold - for lineno, offset, text, check in McCabeChecker(tree, filename).run(): - complx.append('%s:%d:1: %s' % (filename, lineno, text)) - - if len(complx) == 0: - return 0 - print('\n'.join(complx)) - return len(complx) - - -def get_module_complexity(module_path, threshold=7): - """Returns the complexity of a module""" - with open(module_path, "rU") as mod: - code = mod.read() - return get_code_complexity(code, threshold, filename=module_path) - - -def _read(filename): - if (2, 5) < sys.version_info < (3, 0): - with open(filename, 'rU') as f: - return f.read() - elif (3, 0) <= sys.version_info < (4, 0): - """Read the source code.""" - try: - with open(filename, 'rb') as f: - (encoding, _) = tokenize.detect_encoding(f.readline) - except (LookupError, SyntaxError, UnicodeError): - # Fall back if file encoding is improperly declared - with open(filename, encoding='latin-1') as f: - return f.read() - with open(filename, 'r', encoding=encoding) as f: - return f.read() - - -def main(argv=None): - if argv is None: - argv = sys.argv[1:] - opar = optparse.OptionParser() - opar.add_option("-d", "--dot", dest="dot", - help="output a graphviz dot file", action="store_true") - opar.add_option("-m", "--min", dest="threshold", - help="minimum complexity for output", type="int", - default=1) - - options, args = opar.parse_args(argv) - - code = _read(args[0]) - tree = compile(code, args[0], "exec", ast.PyCF_ONLY_AST) - visitor = PathGraphingAstVisitor() - visitor.preorder(tree, visitor) - - if options.dot: - print('graph {') - for graph in visitor.graphs.values(): - if (not options.threshold or - graph.complexity() >= options.threshold): - graph.to_dot() - print('}') - else: - for graph in visitor.graphs.values(): - if graph.complexity() >= options.threshold: - print(graph.name, graph.complexity()) - - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/INSTALLER b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/LICENSE.txt b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/LICENSE.txt deleted file mode 100644 index 737fec5c..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2019 The pip developers (see AUTHORS.txt file) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/METADATA b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/METADATA deleted file mode 100644 index 1413a044..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/METADATA +++ /dev/null @@ -1,87 +0,0 @@ -Metadata-Version: 2.1 -Name: pip -Version: 20.1.1 -Summary: The PyPA recommended tool for installing Python packages. -Home-page: https://pip.pypa.io/ -Author: The pip developers -Author-email: pypa-dev@groups.google.com -License: MIT -Project-URL: Documentation, https://pip.pypa.io -Project-URL: Source, https://github.com/pypa/pip -Keywords: distutils easy_install egg setuptools wheel virtualenv -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Topic :: Software Development :: Build Tools -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.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.* - -pip - The Python Package Installer -================================== - -.. image:: https://img.shields.io/pypi/v/pip.svg - :target: https://pypi.org/project/pip/ - -.. image:: https://readthedocs.org/projects/pip/badge/?version=latest - :target: https://pip.pypa.io/en/latest - -pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. - -Please take a look at our documentation for how to install and use pip: - -* `Installation`_ -* `Usage`_ - -We release updates regularly, with a new version every 3 months. Find more details in our documentation: - -* `Release notes`_ -* `Release process`_ - -In 2020, we're working on improvements to the heart of pip. Please `learn more and take our survey`_ to help us do it right. - -If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: - -* `Issue tracking`_ -* `Discourse channel`_ -* `User IRC`_ - -If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: - -* `GitHub page`_ -* `Development documentation`_ -* `Development mailing list`_ -* `Development IRC`_ - -Code of Conduct ---------------- - -Everyone interacting in the pip project's codebases, issue trackers, chat -rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. - -.. _package installer: https://packaging.python.org/guides/tool-recommendations/ -.. _Python Package Index: https://pypi.org -.. _Installation: https://pip.pypa.io/en/stable/installing.html -.. _Usage: https://pip.pypa.io/en/stable/ -.. _Release notes: https://pip.pypa.io/en/stable/news.html -.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ -.. _GitHub page: https://github.com/pypa/pip -.. _Development documentation: https://pip.pypa.io/en/latest/development -.. _learn more and take our survey: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html -.. _Issue tracking: https://github.com/pypa/pip/issues -.. _Discourse channel: https://discuss.python.org/c/packaging -.. _Development mailing list: https://groups.google.com/forum/#!forum/pypa-dev -.. _User IRC: https://webchat.freenode.net/?channels=%23pypa -.. _Development IRC: https://webchat.freenode.net/?channels=%23pypa-dev -.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ - - diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/RECORD b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/RECORD deleted file mode 100644 index 008a269a..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/RECORD +++ /dev/null @@ -1,272 +0,0 @@ -../../../bin/pip,sha256=nsWfaXTJiqw9macEHdRQ2hoB6jOzquT67HSkpsKR2dQ,269 -../../../bin/pip3,sha256=nsWfaXTJiqw9macEHdRQ2hoB6jOzquT67HSkpsKR2dQ,269 -../../../bin/pip3.8,sha256=nsWfaXTJiqw9macEHdRQ2hoB6jOzquT67HSkpsKR2dQ,269 -pip-20.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip-20.1.1.dist-info/LICENSE.txt,sha256=W6Ifuwlk-TatfRU2LR7W1JMcyMj5_y1NkRkOEJvnRDE,1090 -pip-20.1.1.dist-info/METADATA,sha256=dwRFheMvgIBpyZllM4tVlf5TfjoXc1ZxlsJf0ze61_M,3634 -pip-20.1.1.dist-info/RECORD,, -pip-20.1.1.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -pip-20.1.1.dist-info/entry_points.txt,sha256=HtfDOwpUlr9s73jqLQ6wF9V0_0qvUXJwCBz7Vwx0Ue0,125 -pip-20.1.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip/__init__.py,sha256=9lnkMA2mCKfgnTkqep7tMbosgEJ4rENcyu2tcqDwUNw,455 -pip/__main__.py,sha256=bqCAM1cj1HwHCDx3WJa-LJxOBXimGxE8OjBqAvnhVg0,911 -pip/__pycache__/__init__.cpython-38.pyc,, -pip/__pycache__/__main__.cpython-38.pyc,, -pip/_internal/__init__.py,sha256=2si23JBW1erg19xIJ8CD6tfGknz0ijtXmzuXjGfGMGE,495 -pip/_internal/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/__pycache__/build_env.cpython-38.pyc,, -pip/_internal/__pycache__/cache.cpython-38.pyc,, -pip/_internal/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/__pycache__/exceptions.cpython-38.pyc,, -pip/_internal/__pycache__/locations.cpython-38.pyc,, -pip/_internal/__pycache__/main.cpython-38.pyc,, -pip/_internal/__pycache__/pyproject.cpython-38.pyc,, -pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc,, -pip/_internal/__pycache__/wheel_builder.cpython-38.pyc,, -pip/_internal/build_env.py,sha256=2P0xaKpDhEfrA5P7cXnbx9QpL52Hc1Uturp8EIcjGRg,7506 -pip/_internal/cache.py,sha256=aXPdcihRKQVH26jl1cxSKTmTnV0_hNMs7cGADMUFi1Y,12334 -pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 -pip/_internal/cli/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc,, -pip/_internal/cli/__pycache__/base_command.cpython-38.pyc,, -pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc,, -pip/_internal/cli/__pycache__/command_context.cpython-38.pyc,, -pip/_internal/cli/__pycache__/main.cpython-38.pyc,, -pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc,, -pip/_internal/cli/__pycache__/req_command.cpython-38.pyc,, -pip/_internal/cli/__pycache__/spinners.cpython-38.pyc,, -pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc,, -pip/_internal/cli/autocompletion.py,sha256=ekGNtcDI0p7rFVc-7s4T9Tbss4Jgb7vsB649XJIblRg,6547 -pip/_internal/cli/base_command.py,sha256=O5fT5HHfc_UYNvhqK0rjfh_13K3fIVQzcKUF4xKbFts,8024 -pip/_internal/cli/cmdoptions.py,sha256=6m_aB70I097DJygO3Uh065ow5Mq1XKsGX-WozPoVX7I,28402 -pip/_internal/cli/command_context.py,sha256=ygMVoTy2jpNilKT-6416gFSQpaBtrKRBbVbi2fy__EU,975 -pip/_internal/cli/main.py,sha256=Hxc9dZyW3xiDsYZX-_J2cGXT5DWNLNn_Y7o9oUme-Ec,2616 -pip/_internal/cli/main_parser.py,sha256=voAtjo4WVPIYeu7Fqabva9SXaB3BjG0gH93GBfe6jHQ,2843 -pip/_internal/cli/parser.py,sha256=4FfwW8xB84CrkLs35ud90ZkhCcWyVkx17XD6j3XCW7c,9480 -pip/_internal/cli/progress_bars.py,sha256=WtKOHkePvHwnlhDUotAmKpjBH6hBdVTOnxSiiuCC2l8,9031 -pip/_internal/cli/req_command.py,sha256=NajtG3IfB3YkiM7LANLttyJTfPtgB-3CTErY0YR0k50,15309 -pip/_internal/cli/spinners.py,sha256=PS9s53LB5aDPelIn8FhKerK3bOdgeefFH5wSWJ2PCzI,5509 -pip/_internal/cli/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 -pip/_internal/commands/__init__.py,sha256=yoLAnmEXjoQgYfDuwsuWG3RzzD19oeHobGEhmpIYsB4,4100 -pip/_internal/commands/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/commands/__pycache__/cache.cpython-38.pyc,, -pip/_internal/commands/__pycache__/check.cpython-38.pyc,, -pip/_internal/commands/__pycache__/completion.cpython-38.pyc,, -pip/_internal/commands/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/commands/__pycache__/debug.cpython-38.pyc,, -pip/_internal/commands/__pycache__/download.cpython-38.pyc,, -pip/_internal/commands/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/commands/__pycache__/hash.cpython-38.pyc,, -pip/_internal/commands/__pycache__/help.cpython-38.pyc,, -pip/_internal/commands/__pycache__/install.cpython-38.pyc,, -pip/_internal/commands/__pycache__/list.cpython-38.pyc,, -pip/_internal/commands/__pycache__/search.cpython-38.pyc,, -pip/_internal/commands/__pycache__/show.cpython-38.pyc,, -pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc,, -pip/_internal/commands/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/commands/cache.py,sha256=LZCLVEYCr5Ugh81Zt07Hz5v6SIt0QQzr2-npj3M44aE,5676 -pip/_internal/commands/check.py,sha256=fqRrz2uKPC8Qsx2rgLygAD2Rbr-qxp1Q55zUoyZzB9Q,1677 -pip/_internal/commands/completion.py,sha256=BoEW3RZQZhsZe5to1aOe245dcBLkf-PTCJL7_u9A-Es,2957 -pip/_internal/commands/configuration.py,sha256=y74Vl2p41dBOE2NwUzW4YqnbGbl9r0lsCyBlHguDAWA,7206 -pip/_internal/commands/debug.py,sha256=e02Tb4jG7RhyrxTjCRGo8J-Oy92Y7AhXp8L9JYJUj5w,8153 -pip/_internal/commands/download.py,sha256=thDfHi0qY6DQ_1GkYPTutwta3tA0RaHJhKycepC4FgA,4740 -pip/_internal/commands/freeze.py,sha256=gtUPVHnJ2qyx1o8E6e1ZkMTRzk8rGD6YJI1olILEYC4,3359 -pip/_internal/commands/hash.py,sha256=KckEd5FeomfsRgZmRzhJRPYSsz-HXbFZGNdrzp12ftQ,1742 -pip/_internal/commands/help.py,sha256=s8bDMJbRVxs9ehLKuD4mXTsv1bTRapy1jDwaTCE90qw,1193 -pip/_internal/commands/install.py,sha256=kKjVLbM30lHb2QmDvTyVHm3RGybaZyGTdE4AESPrd9k,26464 -pip/_internal/commands/list.py,sha256=QKQt4z9hVYYxU7vwHGubR2in2cuS_K-alUvC5WGUJ7s,10238 -pip/_internal/commands/search.py,sha256=KjAz-s9mwkiLfDd-cpQO3pL6KFoOyl1RKlvxnJj3zz8,5191 -pip/_internal/commands/show.py,sha256=RqSX_KvzcZWz1gxIOZEnnk4-VeSkNvr0yWz5jF6JrcY,6791 -pip/_internal/commands/uninstall.py,sha256=D2Otze7J-RJvjfozRq2Yon9NKJrg4cbBGFuXyEwBMR0,3202 -pip/_internal/commands/wheel.py,sha256=oxyo51V1m_Hu4U-HCS53vBx5-82Q6GOhn1doOgAr3KE,6431 -pip/_internal/configuration.py,sha256=k3Y3HMMMm_fzNqX75QoNuHvjX8tplmNBuIJJpDHmf9M,14349 -pip/_internal/distributions/__init__.py,sha256=ECBUW5Gtu9TjJwyFLvim-i6kUMYVuikNh9I5asL6tbA,959 -pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/base.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/installed.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/distributions/base.py,sha256=ruprpM_L2T2HNi3KLUHlbHimZ1sWVw-3Q0Lb8O7TDAI,1425 -pip/_internal/distributions/installed.py,sha256=YqlkBKr6TVP1MAYS6SG8ojud21wVOYLMZ8jMLJe9MSU,760 -pip/_internal/distributions/sdist.py,sha256=D4XTMlCwgPlK69l62GLYkNSVTVe99fR5iAcVt2EbGok,4086 -pip/_internal/distributions/wheel.py,sha256=95uD-TfaYoq3KiKBdzk9YMN4RRqJ28LNoSTS2K46gek,1294 -pip/_internal/exceptions.py,sha256=B3tSkzheqSfGoGt5OcAOhLhfnWWMzfJ60URvZWwkwHw,10308 -pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30 -pip/_internal/index/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/index/__pycache__/collector.cpython-38.pyc,, -pip/_internal/index/__pycache__/package_finder.cpython-38.pyc,, -pip/_internal/index/collector.py,sha256=tFpQdkBlbNzdwlep7a5_o9unymgWuEmo2WtARsagiao,21547 -pip/_internal/index/package_finder.py,sha256=2Uq4RPSRboyRPj1Zp3-SB8ZFNLAEMrZv6G2yH-wVjIA,37676 -pip/_internal/locations.py,sha256=vXf8886o1_lUY3jnT-0RMG1Puo64TgiuMIzccVawP4A,6873 -pip/_internal/main.py,sha256=IVBnUQ-FG7DK6617uEXRB5_QJqspAsBFmTmTesYkbdQ,437 -pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 -pip/_internal/models/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/models/__pycache__/candidate.cpython-38.pyc,, -pip/_internal/models/__pycache__/direct_url.cpython-38.pyc,, -pip/_internal/models/__pycache__/format_control.cpython-38.pyc,, -pip/_internal/models/__pycache__/index.cpython-38.pyc,, -pip/_internal/models/__pycache__/link.cpython-38.pyc,, -pip/_internal/models/__pycache__/scheme.cpython-38.pyc,, -pip/_internal/models/__pycache__/search_scope.cpython-38.pyc,, -pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc,, -pip/_internal/models/__pycache__/target_python.cpython-38.pyc,, -pip/_internal/models/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/models/candidate.py,sha256=Y58Bcm6oXUj0iS-yhmerlGo5CQJI2p0Ww9h6hR9zQDw,1150 -pip/_internal/models/direct_url.py,sha256=MnBLPci1hE9Ndh6d3m0LAqB7hX3ci80CCJTE5eerFaQ,6900 -pip/_internal/models/format_control.py,sha256=ICzVjjGwfZYdX-eLLKHjMHLutEJlAGpfj09OG_eMqac,2673 -pip/_internal/models/index.py,sha256=K59A8-hVhBM20Xkahr4dTwP7OjkJyEqXH11UwHFVgqM,1060 -pip/_internal/models/link.py,sha256=KobEaGViwOzyPBD7kgzpGqyrQfh5zjlonOStCGAhl2U,7302 -pip/_internal/models/scheme.py,sha256=vvhBrrno7eVDXcdKHiZWwxhPHf4VG5uSCEkC0QDR2RU,679 -pip/_internal/models/search_scope.py,sha256=AYbFyfEen5cx0kRZTMgUWUxzcMr5nDk32MO4S67Ror4,4712 -pip/_internal/models/selection_prefs.py,sha256=rPeif2KKjhTPXeMoQYffjqh10oWpXhdkxRDaPT1HO8k,1908 -pip/_internal/models/target_python.py,sha256=bbOSwPmojPMtCW6i2XMNjVJzt_2GQYfx3FcGQY8pL44,3842 -pip/_internal/models/wheel.py,sha256=FTfzVb4WIbfIehxhdlAVvCil_MQ0-W44oyN56cE6NHc,2772 -pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50 -pip/_internal/network/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/network/__pycache__/auth.cpython-38.pyc,, -pip/_internal/network/__pycache__/cache.cpython-38.pyc,, -pip/_internal/network/__pycache__/download.cpython-38.pyc,, -pip/_internal/network/__pycache__/session.cpython-38.pyc,, -pip/_internal/network/__pycache__/utils.cpython-38.pyc,, -pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc,, -pip/_internal/network/auth.py,sha256=HJg5peC3gL44H7pmZhCPnu2MrwpAalOSF7d1jmNDqt8,11125 -pip/_internal/network/cache.py,sha256=51CExcRkXWrgMZ7WsrZ6cmijKfViD5tVgKbBvJHO1IE,2394 -pip/_internal/network/download.py,sha256=MIisedL1oFOSrYAN119HDlIuFfw6eL6CNY7oJhHIzUc,6269 -pip/_internal/network/session.py,sha256=Zs0uiyPxTpfpgSv-ZI9hK9TjasmTplBuBivOTcUiJME,15208 -pip/_internal/network/utils.py,sha256=iiixo1OeaQ3niUWiBjg59PN6f1w7vvTww1vFriTD_IU,1959 -pip/_internal/network/xmlrpc.py,sha256=AL115M3vFJ8xiHVJneb8Hi0ZFeRvdPhblC89w25OG5s,1597 -pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/operations/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/__pycache__/check.cpython-38.pyc,, -pip/_internal/operations/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/operations/__pycache__/prepare.cpython-38.pyc,, -pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc,, -pip/_internal/operations/build/metadata.py,sha256=yHMi5gHYXcXyHcvUPWHdO-UyOo3McFWljn_nHfM1O9c,1307 -pip/_internal/operations/build/metadata_legacy.py,sha256=VgzBTk8naIO8-8N_ifEYF7ZAxWUDhphWVIaVlZ2FqYM,2011 -pip/_internal/operations/build/wheel.py,sha256=ntltdNP6D2Tpr4V0agssu6rE0F9LaBpJkYT6zSdhEbw,1469 -pip/_internal/operations/build/wheel_legacy.py,sha256=N1aqNZyGURBX0Bj6wPmB0t4866oMbxoHUpC9pz6FyT0,3356 -pip/_internal/operations/check.py,sha256=a6uHG0daoWpmSPCdL7iYJaGQYZ-CRvPvTnCv2PnIIs0,5353 -pip/_internal/operations/freeze.py,sha256=mGT2OFjMOb0FlVjgedAzJ9GbNOgNwYiL0130xx60pHA,10587 -pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51 -pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/operations/install/editable_legacy.py,sha256=rJ_xs2qtDUjpY2-n6eYlVyZiNoKbOtZXZrYrcnIELt4,1488 -pip/_internal/operations/install/legacy.py,sha256=YkKdL_tyNwDP2huOGxmopySh5Pz2v_wRVeSTEa6ZUco,4686 -pip/_internal/operations/install/wheel.py,sha256=8IO3GYTtrJ42cqipLOh0rxex4j-PfU8m71HVB0tOQd0,23885 -pip/_internal/operations/prepare.py,sha256=RDwtSetVTfv-nv1-_apYBA3Dez5ngBmOYzcuZy2Q3vk,20030 -pip/_internal/pyproject.py,sha256=VJKsrXORGiGoDPVKCQhuu4tWlQSTOhoiRlVLRNu4rx4,7400 -pip/_internal/req/__init__.py,sha256=UVaYPlHZVGRBQQPjvGC_6jJDQtewXm0ws-8Lxhg_TiY,2671 -pip/_internal/req/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/req/__pycache__/constructors.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_file.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_install.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_set.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc,, -pip/_internal/req/constructors.py,sha256=i_dU2sYtSk5GMsad68gBx26tfneRmhPF2sYGe4uPnu8,15441 -pip/_internal/req/req_file.py,sha256=5QlZr36kkw1Jsbr8vFO-fGUEAef9h-AoRRqjx8EYSuQ,19075 -pip/_internal/req/req_install.py,sha256=9yn_fBFTyzHPMjYG5WXBB2WiGQvk3BT6gYl9Khw8ZoE,31713 -pip/_internal/req/req_set.py,sha256=EBHZ9zWSR8arxjcadyU2OotZIECemM8oOFQ0nK-Bb7E,7792 -pip/_internal/req/req_tracker.py,sha256=cAKhSw-QbhGxqPF1Wc0zD6jo932jpdYF3ROfRSH8hes,4744 -pip/_internal/req/req_uninstall.py,sha256=NdErRQBpNScsdwJAo3O_zo2KPPfQyVMJ_Q2mxPWYyOA,23734 -pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/resolution/__pycache__/base.cpython-38.pyc,, -pip/_internal/resolution/base.py,sha256=xi72YmIS-lEjyK13PN_3qkGGthA4yGoK0C6qWynyHrE,682 -pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc,, -pip/_internal/resolution/legacy/resolver.py,sha256=56GuGHWcseV24cvTCOuRHMAF_Er1UeDxn5m18XMkHBs,17587 -pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc,, -pip/_internal/resolution/resolvelib/base.py,sha256=l2Z3-1Qg243lWzwFbaN17qixA4U8LYr-qMhZTdaHROc,1502 -pip/_internal/resolution/resolvelib/candidates.py,sha256=wzi9t3aX1Twi3xTNEkpG6eWOd0dEg5uKul-QkK3arvw,15173 -pip/_internal/resolution/resolvelib/factory.py,sha256=mDs3p8D9N9zfYvn_iIx0saDLHF1SF7KHBQlA1gWSWVQ,7574 -pip/_internal/resolution/resolvelib/provider.py,sha256=0fKuPuEoD5T7w-YwKgQZc1AmgSnAkrxGnLBOf-_6Kiw,1703 -pip/_internal/resolution/resolvelib/requirements.py,sha256=bu9Y4YINHjvBm-NBKvnxw9IYHW4t6rRlm4-QKVqLDsM,3872 -pip/_internal/resolution/resolvelib/resolver.py,sha256=3LXhhCz6CtIpih8tK2nHeRvVEjVJmXrqxNCM1FQM1U0,6673 -pip/_internal/self_outdated_check.py,sha256=3KO1pTJUuYaiV9X0t87I9PimkGL82HbhLWbocqKZpBU,8009 -pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/utils/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc,, -pip/_internal/utils/__pycache__/compat.cpython-38.pyc,, -pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc,, -pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc,, -pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc,, -pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc,, -pip/_internal/utils/__pycache__/encoding.cpython-38.pyc,, -pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc,, -pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc,, -pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc,, -pip/_internal/utils/__pycache__/glibc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/hashes.cpython-38.pyc,, -pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc,, -pip/_internal/utils/__pycache__/logging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/misc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/models.cpython-38.pyc,, -pip/_internal/utils/__pycache__/packaging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/pkg_resources.cpython-38.pyc,, -pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc,, -pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc,, -pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc,, -pip/_internal/utils/__pycache__/typing.cpython-38.pyc,, -pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc,, -pip/_internal/utils/__pycache__/urls.cpython-38.pyc,, -pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc,, -pip/_internal/utils/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/utils/appdirs.py,sha256=RZzUG-Bkh2b-miX0DSZ3v703_-bgK-v0PfWCCjwVE9g,1349 -pip/_internal/utils/compat.py,sha256=ZRJsXMjq373p0US54CUkKRkpLH-ioOM3H3yAhmbUPcs,8898 -pip/_internal/utils/compatibility_tags.py,sha256=b2NWEbxfsrB2pBLwJkNVSYUrIAsumQ2IWDoNabbwLPs,5492 -pip/_internal/utils/deprecation.py,sha256=pBnNogoA4UGTxa_JDnPXBRRYpKMbExAhXpBwAwklOBs,3318 -pip/_internal/utils/direct_url_helpers.py,sha256=bZCBNwPQVyZpYGjX_VcomvVvRHvKw-9JzEV-Ft09LQc,4359 -pip/_internal/utils/distutils_args.py,sha256=a56mblNxk9BGifbpEETG61mmBrqhjtjRkJ4HYn-oOEE,1350 -pip/_internal/utils/encoding.py,sha256=hxZz0t3Whw3d4MHQEiofxalTlfKwxFdLc8fpeGfhKo8,1320 -pip/_internal/utils/entrypoints.py,sha256=vHcNpnksCv6mllihU6hfifdsKPEjwcaJ1aLIXEaynaU,1152 -pip/_internal/utils/filesystem.py,sha256=fqpFwT280152rlX1RjJqjoLp_MXVA8HzKTtDmsl15Ps,6813 -pip/_internal/utils/filetypes.py,sha256=R2FwzoeX7b-rZALOXx5cuO8VPPMhUQ4ne7wm3n3IcWA,571 -pip/_internal/utils/glibc.py,sha256=LOeNGgawCKS-4ke9fii78fwXD73dtNav3uxz1Bf-Ab8,3297 -pip/_internal/utils/hashes.py,sha256=LQVOt2LTWAdBJH6WPim1YGdF0J-0AfBBLghIDlY1-80,3986 -pip/_internal/utils/inject_securetransport.py,sha256=M17ZlFVY66ApgeASVjKKLKNz0LAfk-SyU0HZ4ZB6MmI,810 -pip/_internal/utils/logging.py,sha256=YIfuDUEkmdn9cIRQ_Ec8rgXs1m5nOwDECtZqM4CBH5U,13093 -pip/_internal/utils/misc.py,sha256=d6Gvup_5Uus2jBxsUHwnSP1HDiGsb9oBNZKhdgbAMnE,26798 -pip/_internal/utils/models.py,sha256=IA0hw_T4awQzui0kqfIEASm5yLtgZAB08ag59Nip5G8,1148 -pip/_internal/utils/packaging.py,sha256=VtiwcAAL7LBi7tGL2je7LeW4bE11KMHGCsJ1NZY5XtM,3035 -pip/_internal/utils/pkg_resources.py,sha256=ZX-k7V5q_aNWyDse92nN7orN1aCpRLsaxzpkBZ1XKzU,1254 -pip/_internal/utils/setuptools_build.py,sha256=E1KswI7wfNnCDE5R6G8c9ZbByENpu7NqocjY26PCQDw,5058 -pip/_internal/utils/subprocess.py,sha256=vI2QWpNDqM-dkn-z8i1Yrfxnn5sYniPeWn6FhTxX4dY,9902 -pip/_internal/utils/temp_dir.py,sha256=H8yUBrRWqTM83cuUu7jVvw_xKL9eZtg_IIbXQtjMLlA,8185 -pip/_internal/utils/typing.py,sha256=xkYwOeHlf4zsHXBDC4310HtEqwhQcYXFPq2h35Tcrl0,1401 -pip/_internal/utils/unpacking.py,sha256=M944JTSiapBOSKLWu7lbawpVHSE7flfzZTEr3TAG7v8,9438 -pip/_internal/utils/urls.py,sha256=q2rw1kMiiig_XZcoyJSsWMJQqYw-2wUmrMoST4mCW_I,1527 -pip/_internal/utils/virtualenv.py,sha256=iVJ8ZlbNtGon6I4uZFsY2SidrUf1vt3YHrgS5CuU98w,3553 -pip/_internal/utils/wheel.py,sha256=ofsZEN35YhSxRYC4gfzpTtqa_UQ8GF1tl4jtyUdd0gU,7306 -pip/_internal/vcs/__init__.py,sha256=viJxJRqRE_mVScum85bgQIXAd6o0ozFt18VpC-qIJrM,617 -pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/git.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc,, -pip/_internal/vcs/bazaar.py,sha256=84q1-kj1_nJ9AMzMu8RmMp-riRZu81M7K9kowcYgi3U,3957 -pip/_internal/vcs/git.py,sha256=wlvvVT-hPRwCvkihEoOCZmkCzMzosmV43_DTPvEVA_M,14165 -pip/_internal/vcs/mercurial.py,sha256=wVdmoFH-RYoaxjtuAqw40b0daMPX-Fr_26W1ME_9HZU,5347 -pip/_internal/vcs/subversion.py,sha256=6shByxeASetbM7WCj6WNoPcuLfBK65DoOEqbkSiWPAI,12331 -pip/_internal/vcs/versioncontrol.py,sha256=RtSrHr96CynqXYBQIC61cVY_9C0e7hk8dXUV-BpHmpI,23591 -pip/_internal/wheel_builder.py,sha256=p9ZFawfCR1GXchTRY6oq7Qx5enLLjs2SouafNFNsAAE,9590 -pip/_vendor/__init__.py,sha256=9W5OMec7OR5iGiLkewOfrMJ9Wt-FjLAezVSYzwHc2ds,5156 -pip/_vendor/__pycache__/__init__.cpython-38.pyc,, diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/WHEEL b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/WHEEL deleted file mode 100644 index ef99c6cf..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.34.2) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/entry_points.txt b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/entry_points.txt deleted file mode 100644 index d48bd8a8..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/entry_points.txt +++ /dev/null @@ -1,5 +0,0 @@ -[console_scripts] -pip = pip._internal.cli.main:main -pip3 = pip._internal.cli.main:main -pip3.8 = pip._internal.cli.main:main - diff --git a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/top_level.txt b/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/top_level.txt deleted file mode 100644 index a1b589e3..00000000 --- a/env/lib/python3.8/site-packages/pip-20.1.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/env/lib/python3.8/site-packages/pip/__init__.py b/env/lib/python3.8/site-packages/pip/__init__.py deleted file mode 100644 index 3dcf3a9d..00000000 --- a/env/lib/python3.8/site-packages/pip/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional - - -__version__ = "20.1.1" - - -def main(args=None): - # type: (Optional[List[str]]) -> int - """This is an internal API only meant for use by pip's own console scripts. - - For additional details, see https://github.com/pypa/pip/issues/7498. - """ - from pip._internal.utils.entrypoints import _wrapper - - return _wrapper(args) diff --git a/env/lib/python3.8/site-packages/pip/__main__.py b/env/lib/python3.8/site-packages/pip/__main__.py deleted file mode 100644 index 7c2505fa..00000000 --- a/env/lib/python3.8/site-packages/pip/__main__.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import absolute_import - -import os -import sys - -# Remove '' and current working directory from the first entry -# of sys.path, if present to avoid using current directory -# in pip commands check, freeze, install, list and show, -# when invoked as python -m pip -if sys.path[0] in ('', os.getcwd()): - sys.path.pop(0) - -# If we are running from a wheel, add the wheel to sys.path -# This allows the usage python pip-*.whl/pip install pip-*.whl -if __package__ == '': - # __file__ is pip-*.whl/pip/__main__.py - # first dirname call strips of '/__main__.py', second strips off '/pip' - # Resulting path is the name of the wheel itself - # Add that to sys.path so we can import pip - path = os.path.dirname(os.path.dirname(__file__)) - sys.path.insert(0, path) - -from pip._internal.cli.main import main as _main # isort:skip # noqa - -if __name__ == '__main__': - sys.exit(_main()) diff --git a/env/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0d7adf8408b8985ee0ccae667256f3ffe86a666e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 629 zcmZuv!EV$r5VezR8kSZ^Tacg#A<(MO3J4WYiRNN?V|UjgaV*e#Z#?@ZhqA03L(e9S9t8 zT%!h;7$boV0UXpp6P95Ul@UffEJu8ek9hnUmobmtpfvdj_fU$5>o1QFkLh%OZ~C0R zJ}QcX;#nFD(FCx-{5Rdr7q!IUE>ts$KiWY!Zc^({-uUQV9xwN(uHotdw_kOk_ zGQJrYK|+^?X)O#iz6qHb{i`zT98hOMIn(PFPOTaFJ1`(-<`>`_G6|gh+R9y{eW6LG zG^^eVK3Oh=s3*JKtiLns>y-!!+|p5+>3)bBCY66?8$m$vdSEwLM**M8d_2x-c^fFQS$DnPL; zYcST0wbUt>r3JsC(xsAVFf=R}M4fqH1-54~c$D@XnG-+l()ZcS7JBAIrcD_PK};Vu u0BU;CEOzIMoeHzr-!D?VbID~ int - """This is preserved for old console scripts that may still be referencing - it. - - For additional details, see https://github.com/pypa/pip/issues/7498. - """ - from pip._internal.utils.entrypoints import _wrapper - - return _wrapper(args) diff --git a/env/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 5a56d0895ae04a2092c0ffa66cc58b1c95012fbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 678 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 MwDj@P(o*?<0m?w->i_@% diff --git a/env/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc deleted file mode 100644 index 5d95f07e814b7a5aa151828fe7484b9685cbcb19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10808 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc deleted file mode 100644 index b3fd9f442bc1b9f81c6c6da0839dd9fe05caedf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3732 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc deleted file mode 100644 index 9dab7b7853c8e42ccf679398fdf21fe23ed318f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5493 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/build_env.py b/env/lib/python3.8/site-packages/pip/_internal/build_env.py deleted file mode 100644 index b8f005f5..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/build_env.py +++ /dev/null @@ -1,219 +0,0 @@ -"""Build Environment used for isolation during sdist building -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False -# mypy: disallow-untyped-defs=False - -import logging -import os -import sys -import textwrap -from collections import OrderedDict -from distutils.sysconfig import get_python_lib -from sysconfig import get_paths - -from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet - -from pip import __file__ as pip_location -from pip._internal.cli.spinners import open_spinner -from pip._internal.utils.subprocess import call_subprocess -from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Tuple, Set, Iterable, Optional, List - from pip._internal.index.package_finder import PackageFinder - -logger = logging.getLogger(__name__) - - -class _Prefix: - - def __init__(self, path): - # type: (str) -> None - self.path = path - self.setup = False - self.bin_dir = get_paths( - 'nt' if os.name == 'nt' else 'posix_prefix', - vars={'base': path, 'platbase': path} - )['scripts'] - # Note: prefer distutils' sysconfig to get the - # library paths so PyPy is correctly supported. - purelib = get_python_lib(plat_specific=False, prefix=path) - platlib = get_python_lib(plat_specific=True, prefix=path) - if purelib == platlib: - self.lib_dirs = [purelib] - else: - self.lib_dirs = [purelib, platlib] - - -class BuildEnvironment(object): - """Creates and manages an isolated environment to install build deps - """ - - def __init__(self): - # type: () -> None - temp_dir = TempDirectory( - kind=tempdir_kinds.BUILD_ENV, globally_managed=True - ) - - self._prefixes = OrderedDict(( - (name, _Prefix(os.path.join(temp_dir.path, name))) - for name in ('normal', 'overlay') - )) - - self._bin_dirs = [] # type: List[str] - self._lib_dirs = [] # type: List[str] - for prefix in reversed(list(self._prefixes.values())): - self._bin_dirs.append(prefix.bin_dir) - self._lib_dirs.extend(prefix.lib_dirs) - - # Customize site to: - # - ensure .pth files are honored - # - prevent access to system site packages - system_sites = { - os.path.normcase(site) for site in ( - get_python_lib(plat_specific=False), - get_python_lib(plat_specific=True), - ) - } - self._site_dir = os.path.join(temp_dir.path, 'site') - if not os.path.exists(self._site_dir): - os.mkdir(self._site_dir) - with open(os.path.join(self._site_dir, 'sitecustomize.py'), 'w') as fp: - fp.write(textwrap.dedent( - ''' - import os, site, sys - - # First, drop system-sites related paths. - original_sys_path = sys.path[:] - known_paths = set() - for path in {system_sites!r}: - site.addsitedir(path, known_paths=known_paths) - system_paths = set( - os.path.normcase(path) - for path in sys.path[len(original_sys_path):] - ) - original_sys_path = [ - path for path in original_sys_path - if os.path.normcase(path) not in system_paths - ] - sys.path = original_sys_path - - # Second, add lib directories. - # ensuring .pth file are processed. - for path in {lib_dirs!r}: - assert not path in sys.path - site.addsitedir(path) - ''' - ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)) - - def __enter__(self): - self._save_env = { - name: os.environ.get(name, None) - for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH') - } - - path = self._bin_dirs[:] - old_path = self._save_env['PATH'] - if old_path: - path.extend(old_path.split(os.pathsep)) - - pythonpath = [self._site_dir] - - os.environ.update({ - 'PATH': os.pathsep.join(path), - 'PYTHONNOUSERSITE': '1', - 'PYTHONPATH': os.pathsep.join(pythonpath), - }) - - def __exit__(self, exc_type, exc_val, exc_tb): - for varname, old_value in self._save_env.items(): - if old_value is None: - os.environ.pop(varname, None) - else: - os.environ[varname] = old_value - - def check_requirements(self, reqs): - # type: (Iterable[str]) -> Tuple[Set[Tuple[str, str]], Set[str]] - """Return 2 sets: - - conflicting requirements: set of (installed, wanted) reqs tuples - - missing requirements: set of reqs - """ - missing = set() - conflicting = set() - if reqs: - ws = WorkingSet(self._lib_dirs) - for req in reqs: - try: - if ws.find(Requirement.parse(req)) is None: - missing.add(req) - except VersionConflict as e: - conflicting.add((str(e.args[0].as_requirement()), - str(e.args[1]))) - return conflicting, missing - - def install_requirements( - self, - finder, # type: PackageFinder - requirements, # type: Iterable[str] - prefix_as_string, # type: str - message # type: Optional[str] - ): - # type: (...) -> None - prefix = self._prefixes[prefix_as_string] - assert not prefix.setup - prefix.setup = True - if not requirements: - return - args = [ - sys.executable, os.path.dirname(pip_location), 'install', - '--ignore-installed', '--no-user', '--prefix', prefix.path, - '--no-warn-script-location', - ] # type: List[str] - if logger.getEffectiveLevel() <= logging.DEBUG: - args.append('-v') - for format_control in ('no_binary', 'only_binary'): - formats = getattr(finder.format_control, format_control) - args.extend(('--' + format_control.replace('_', '-'), - ','.join(sorted(formats or {':none:'})))) - - index_urls = finder.index_urls - if index_urls: - args.extend(['-i', index_urls[0]]) - for extra_index in index_urls[1:]: - args.extend(['--extra-index-url', extra_index]) - else: - args.append('--no-index') - for link in finder.find_links: - args.extend(['--find-links', link]) - - for host in finder.trusted_hosts: - args.extend(['--trusted-host', host]) - if finder.allow_all_prereleases: - args.append('--pre') - args.append('--') - args.extend(requirements) - with open_spinner(message) as spinner: - call_subprocess(args, spinner=spinner) - - -class NoOpBuildEnvironment(BuildEnvironment): - """A no-op drop-in replacement for BuildEnvironment - """ - - def __init__(self): - pass - - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - def cleanup(self): - pass - - def install_requirements(self, finder, requirements, prefix, message): - raise NotImplementedError() diff --git a/env/lib/python3.8/site-packages/pip/_internal/cache.py b/env/lib/python3.8/site-packages/pip/_internal/cache.py deleted file mode 100644 index b534f0cf..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cache.py +++ /dev/null @@ -1,349 +0,0 @@ -"""Cache Management -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import hashlib -import json -import logging -import os - -from pip._vendor.packaging.tags import interpreter_name, interpreter_version -from pip._vendor.packaging.utils import canonicalize_name - -from pip._internal.exceptions import InvalidWheelFilename -from pip._internal.models.link import Link -from pip._internal.models.wheel import Wheel -from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.urls import path_to_url - -if MYPY_CHECK_RUNNING: - from typing import Optional, Set, List, Any, Dict - - from pip._vendor.packaging.tags import Tag - - from pip._internal.models.format_control import FormatControl - -logger = logging.getLogger(__name__) - - -def _hash_dict(d): - # type: (Dict[str, str]) -> str - """Return a stable sha224 of a dictionary.""" - s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True) - return hashlib.sha224(s.encode("ascii")).hexdigest() - - -class Cache(object): - """An abstract class - provides cache directories for data from links - - - :param cache_dir: The root of the cache. - :param format_control: An object of FormatControl class to limit - binaries being read from the cache. - :param allowed_formats: which formats of files the cache should store. - ('binary' and 'source' are the only allowed values) - """ - - def __init__(self, cache_dir, format_control, allowed_formats): - # type: (str, FormatControl, Set[str]) -> None - super(Cache, self).__init__() - assert not cache_dir or os.path.isabs(cache_dir) - self.cache_dir = cache_dir or None - self.format_control = format_control - self.allowed_formats = allowed_formats - - _valid_formats = {"source", "binary"} - assert self.allowed_formats.union(_valid_formats) == _valid_formats - - def _get_cache_path_parts_legacy(self, link): - # type: (Link) -> List[str] - """Get parts of part that must be os.path.joined with cache_dir - - Legacy cache key (pip < 20) for compatibility with older caches. - """ - - # We want to generate an url to use as our cache key, we don't want to - # just re-use the URL because it might have other items in the fragment - # and we don't care about those. - key_parts = [link.url_without_fragment] - if link.hash_name is not None and link.hash is not None: - key_parts.append("=".join([link.hash_name, link.hash])) - key_url = "#".join(key_parts) - - # Encode our key url with sha224, we'll use this because it has similar - # security properties to sha256, but with a shorter total output (and - # thus less secure). However the differences don't make a lot of - # difference for our use case here. - hashed = hashlib.sha224(key_url.encode()).hexdigest() - - # We want to nest the directories some to prevent having a ton of top - # level directories where we might run out of sub directories on some - # FS. - parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] - - return parts - - def _get_cache_path_parts(self, link): - # type: (Link) -> List[str] - """Get parts of part that must be os.path.joined with cache_dir - """ - - # We want to generate an url to use as our cache key, we don't want to - # just re-use the URL because it might have other items in the fragment - # and we don't care about those. - key_parts = {"url": link.url_without_fragment} - if link.hash_name is not None and link.hash is not None: - key_parts[link.hash_name] = link.hash - if link.subdirectory_fragment: - key_parts["subdirectory"] = link.subdirectory_fragment - - # Include interpreter name, major and minor version in cache key - # to cope with ill-behaved sdists that build a different wheel - # depending on the python version their setup.py is being run on, - # and don't encode the difference in compatibility tags. - # https://github.com/pypa/pip/issues/7296 - key_parts["interpreter_name"] = interpreter_name() - key_parts["interpreter_version"] = interpreter_version() - - # Encode our key url with sha224, we'll use this because it has similar - # security properties to sha256, but with a shorter total output (and - # thus less secure). However the differences don't make a lot of - # difference for our use case here. - hashed = _hash_dict(key_parts) - - # We want to nest the directories some to prevent having a ton of top - # level directories where we might run out of sub directories on some - # FS. - parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] - - return parts - - def _get_candidates(self, link, canonical_package_name): - # type: (Link, Optional[str]) -> List[Any] - can_not_cache = ( - not self.cache_dir or - not canonical_package_name or - not link - ) - if can_not_cache: - return [] - - formats = self.format_control.get_allowed_formats( - canonical_package_name - ) - if not self.allowed_formats.intersection(formats): - return [] - - candidates = [] - path = self.get_path_for_link(link) - if os.path.isdir(path): - for candidate in os.listdir(path): - candidates.append((candidate, path)) - # TODO remove legacy path lookup in pip>=21 - legacy_path = self.get_path_for_link_legacy(link) - if os.path.isdir(legacy_path): - for candidate in os.listdir(legacy_path): - candidates.append((candidate, legacy_path)) - return candidates - - def get_path_for_link_legacy(self, link): - # type: (Link) -> str - raise NotImplementedError() - - def get_path_for_link(self, link): - # type: (Link) -> str - """Return a directory to store cached items in for link. - """ - raise NotImplementedError() - - def get( - self, - link, # type: Link - package_name, # type: Optional[str] - supported_tags, # type: List[Tag] - ): - # type: (...) -> Link - """Returns a link to a cached item if it exists, otherwise returns the - passed link. - """ - raise NotImplementedError() - - -class SimpleWheelCache(Cache): - """A cache of wheels for future installs. - """ - - def __init__(self, cache_dir, format_control): - # type: (str, FormatControl) -> None - super(SimpleWheelCache, self).__init__( - cache_dir, format_control, {"binary"} - ) - - def get_path_for_link_legacy(self, link): - # type: (Link) -> str - parts = self._get_cache_path_parts_legacy(link) - return os.path.join(self.cache_dir, "wheels", *parts) - - def get_path_for_link(self, link): - # type: (Link) -> str - """Return a directory to store cached wheels for link - - Because there are M wheels for any one sdist, we provide a directory - to cache them in, and then consult that directory when looking up - cache hits. - - We only insert things into the cache if they have plausible version - numbers, so that we don't contaminate the cache with things that were - not unique. E.g. ./package might have dozens of installs done for it - and build a version of 0.0...and if we built and cached a wheel, we'd - end up using the same wheel even if the source has been edited. - - :param link: The link of the sdist for which this will cache wheels. - """ - parts = self._get_cache_path_parts(link) - - # Store wheels within the root cache_dir - return os.path.join(self.cache_dir, "wheels", *parts) - - def get( - self, - link, # type: Link - package_name, # type: Optional[str] - supported_tags, # type: List[Tag] - ): - # type: (...) -> Link - candidates = [] - - if not package_name: - return link - - canonical_package_name = canonicalize_name(package_name) - for wheel_name, wheel_dir in self._get_candidates( - link, canonical_package_name - ): - try: - wheel = Wheel(wheel_name) - except InvalidWheelFilename: - continue - if canonicalize_name(wheel.name) != canonical_package_name: - logger.debug( - "Ignoring cached wheel {} for {} as it " - "does not match the expected distribution name {}.".format( - wheel_name, link, package_name - ) - ) - continue - if not wheel.supported(supported_tags): - # Built for a different python/arch/etc - continue - candidates.append( - ( - wheel.support_index_min(supported_tags), - wheel_name, - wheel_dir, - ) - ) - - if not candidates: - return link - - _, wheel_name, wheel_dir = min(candidates) - return Link(path_to_url(os.path.join(wheel_dir, wheel_name))) - - -class EphemWheelCache(SimpleWheelCache): - """A SimpleWheelCache that creates it's own temporary cache directory - """ - - def __init__(self, format_control): - # type: (FormatControl) -> None - self._temp_dir = TempDirectory( - kind=tempdir_kinds.EPHEM_WHEEL_CACHE, - globally_managed=True, - ) - - super(EphemWheelCache, self).__init__( - self._temp_dir.path, format_control - ) - - -class CacheEntry(object): - def __init__( - self, - link, # type: Link - persistent, # type: bool - ): - self.link = link - self.persistent = persistent - - -class WheelCache(Cache): - """Wraps EphemWheelCache and SimpleWheelCache into a single Cache - - This Cache allows for gracefully degradation, using the ephem wheel cache - when a certain link is not found in the simple wheel cache first. - """ - - def __init__(self, cache_dir, format_control): - # type: (str, FormatControl) -> None - super(WheelCache, self).__init__( - cache_dir, format_control, {'binary'} - ) - self._wheel_cache = SimpleWheelCache(cache_dir, format_control) - self._ephem_cache = EphemWheelCache(format_control) - - def get_path_for_link_legacy(self, link): - # type: (Link) -> str - return self._wheel_cache.get_path_for_link_legacy(link) - - def get_path_for_link(self, link): - # type: (Link) -> str - return self._wheel_cache.get_path_for_link(link) - - def get_ephem_path_for_link(self, link): - # type: (Link) -> str - return self._ephem_cache.get_path_for_link(link) - - def get( - self, - link, # type: Link - package_name, # type: Optional[str] - supported_tags, # type: List[Tag] - ): - # type: (...) -> Link - cache_entry = self.get_cache_entry(link, package_name, supported_tags) - if cache_entry is None: - return link - return cache_entry.link - - def get_cache_entry( - self, - link, # type: Link - package_name, # type: Optional[str] - supported_tags, # type: List[Tag] - ): - # type: (...) -> Optional[CacheEntry] - """Returns a CacheEntry with a link to a cached item if it exists or - None. The cache entry indicates if the item was found in the persistent - or ephemeral cache. - """ - retval = self._wheel_cache.get( - link=link, - package_name=package_name, - supported_tags=supported_tags, - ) - if retval is not link: - return CacheEntry(retval, persistent=True) - - retval = self._ephem_cache.get( - link=link, - package_name=package_name, - supported_tags=supported_tags, - ) - if retval is not link: - return CacheEntry(retval, persistent=False) - - return None diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__init__.py b/env/lib/python3.8/site-packages/pip/_internal/cli/__init__.py deleted file mode 100644 index e589bb91..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Subpackage containing all of pip's command line interface related code -""" - -# This file intentionally does not import submodules diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 93586ac15ffd91fcdf6e2a4cf0149422eacc3d90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmYjMF$w}P5X{*qf`3RS7H0}8LB!6^Mg*~0a>;rI_j2LPA!jZA#c%iwTc2QO<(`!b zGt2D247(W&`hsVBd%%_Vs}=u~uvjooJtix5!X|4m>RguVIt$tyb&k@MK5FNk&!r}k zdi?xN~&%a1;D6^o!aD6M^4 sgf=}N5GkG3Su@ERYCQ$NSg%PLatc_w2rv%Kvo|YBTNBRP58e#%1(tY2xc~qF diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc deleted file mode 100644 index cf33dc915ae237fcf7cb9f648d61e66d96c52bea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4953 zcmb7I-ESMm5#QZA9?26$Nt7Z>isM{9nucvG6-bMuuHwcYLSjUb1x`2A)P} zwsW-{Cmu7j+WA^uk8@$6U91(`cForBRyfoy)k=Dt4~N_3TA8z;Ebn4nAslIs)<)Z7 zwXt@kR%wsd#=%$g?ax_l!XNTWcs}P3`(->QeX+u-BYT$@qxELPNjAL1=|*<~89Ux~ z5;dZBHw=%|@cieWpGY%bs5k68C63aK(viu5QyQVv_pdr^}zZSKeQ^ z@_~Ef*3#0orT40)GA?y?RpD9^NN+U^l(~pis&KtatGuv5XB+$`FesoIXz@RBJ3dd? zCU50snXEx$-YA^(~b4vM~c$T_!alO<+u%Q) zhdxk)6N}B~wbV*lfo5X!ENPXzaBwcI9P-}y;C3MAi*y|OzIw_+LVlJS$2P()#sjhS zS;y&XG~U-n$iKjA`udRXBqRRh!He1wXS5{@I>jNU^Bv!h#`DzP&lft0+;x_tW+!ph zB6$L6@Ka;U*OuK&w{Bi{uU!9dd2!+9!jiIS=ze_t z#?_T?IKa~V&%uT0Qttc+8=# zpv5!j*5MSlD?Og_1BA;%gvn|4d$DCAP>DzU9Z8EJFBf;iX7ZI#V)jRh-~Eco=P~i< z>Ri(9&LKRV-|lq1Ml0~o-`NO)@cd7=S9jlB-3@7O4)Fz{0+C^^5jN*ehq~GBuCnJt z1P}^v7vHCIndmGg*xt#o7|hOVo#Kla4A@WUMj?ilj*|=roz`vY7ox{|BIWlOKnV9w z#hS=8)H>*{YDgp#Cdnd-??B;VR|Y#St|`vA&eHS?=&qr~7CH-m1@_bl$h!IjFJquj zFf%y80lNnaKjREv;ldE`WfI?MCL8_3DBhCiAOn;6#RzGlw6blG`lc1kW>rUtC|3EPv(uDON1nm7GT_$AzSi-By9-iAQj)^TBt0bA zNg45OtjyqUGm$URdoHA8FUfh7(F%5z<#oG3$5*+oge*zNS5}t0)yN66xTpo>7|j+y z)eLHQ<<|1@jfIsJ_x**%Wo5fz)LGXKtA<Ly2p03soVHz#`62vThg7X;WZhx-R4p1-$c->PAIE!Cz5`Qa)h4pC&W5* z9PePdOkk`=j;U_PYomIg73w)0c{}vA7aZ3ks(4hIC=oW4N%aY^aui6F0l8YZ3#+S< zCzZ>Q%CWMt-Bl4!H}qD6P?;FUs=O9@NfLAd{}}6V!dFS(7pWt#snUs<6_7W_zd^@x zHaGbsFLS|1(c8k}1#TK9dOW!$Y*FC0f%dI1El>*JI>*bJuLS;rD1kD{r;Hh15fvf0 zK-jY$n>mZyn1LMO&?*d5ujeUNQqk;(Yi#_wi>YSfL zwy>sIYJ&SRR$B6xN#4)<1*C1f4c6@=X=d{R#TvC0wsm>yW!kq|^cIm}-U|{`!+}Ho zNEwqZ?PL;ty+0OX?YVOp7Fe`Ub-OIf7Ufm6rKqrj<(^Xov;-LAa&E0Rkw&=lhF-VeVk_MAxR zgO$~Sj+Hvv$+sXuzD@fZKz9~(^X(vkDWx*J&Tcg)FA>jW>TXcCNZdSnGJVX0yoDCi zxmj^WgRunQR`?76X@6TVDk!Hh*Pt*r_|caO!RQsV`0wcGyW~KmNaINA;(qpSqyQ3X zMs@(efFpM(;#snv=C&yL+-JI$6u$9!0etz?AV^WQt*hmFFQ<76s8+GMXJsqFToM&O^q@ab&#Y}% z6aQGrD!s`kc>4co(Y0Sz%T1l;z<*W3c(&b)8(9rF^Q>uvdmu_K{1H diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc deleted file mode 100644 index a2f11029e8d66fa4e58f01d43633047100fad9ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5760 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 diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc deleted file mode 100644 index 44125725667b74cc6500ccc1aaa27cea569f1117..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20537 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 It<>xP7brREdH?_b diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc deleted file mode 100644 index 5a3e0d847af3a87ffe417f95fe8e67b5015452af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1311 zcmZuw&2AGh5VpOW&1Rc~LJO5p59OFc69nP_LI@P~PpA<;Z7C}xYrA&Kmi@!)l&0#5 zR`i5;g>vLIcmeLda^e*@F|$b^74^#FvB#d7@0;1pM#Cd8wm*I6KP*Ci;%0K#uz3u# zcmqNZL1U6opHkFW%o5ADO5KX>q~cd7krlNHHam8bs$Wf9-%V-b8Y?gv)8=4 zy3~EjUu^bzYrU10W!yC_RiHCvn%&{^_2F|<-5BI@D^P~ehXaB=_v ziU+ng(d7$azgzI!Z{_rb4G09R{=oP%yhE^vKHeEqQkW` zq$8)eppHRs77HLW(e#*{uyghmi~@9SY5Ro0S`h@CvfgsbF_og9OQo<>#^pRpBh9&) z28Aa9h!JB7{hG#wvv1Vcg^YJ$t#Ka4K~Zr2jr?Bf=p^stQNGwub6{4A#Sd?#j2G|s zcLsNN1~J+?5CM2igSZpMQ70V28;5J>167BJO_+rPg0Loa=+XQoG_=QA|HnrS-i7Gl z0f=L=Pn4(WN1z-yAV>3X!oJk8$F_i>SL7afPF|4hQWFgCY=aG$vU(fKElV}Pi)lV7 z3aNCIrAta>N@0fT3W}M(ViqsfC+WkJ0s#@rV-981rL*j4;W9Ln&q9VzMgw)MLKkLn z0|X)}N<@g{+&ZRTDP&7~ExXKBU586$f~Fyn>@mA7rl!GUrbor)xylYA0c~&*gPMa| z3or}(R|)gj(XGo;zUbV=K1zc`LLYgYCzEQWQ<16mKjWQYJKrp= z<34QnbrctEJ;N563swIPE1Go=|&>!KiSr)&} K@Ux-xb?XlmxjfMT diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc deleted file mode 100644 index 719cd6b1fbf441322e8244c4239a86f09963a7fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1416 zcmZuw-ESi`5VyS_*=&K7msg@|HGIL=5&u$C=ug_hxVXdCW?j^S?T0=IcB^Fq(~I=r6wp>JfD zZ)AL7wS{@2f2(WHYRtmPh6Skc% zPLEEbgU=2RK97zck46tipLU6|hiN61_o&pF#XP|}pR3^l*CjcCRs8{E4zOQ%VppPb z3?QH%$X&ERk}Rzi!bsXLfX>>|nWGo@E3&`~@&x5W8%g)V7vEvDu)yAj)3v2X$+AAT zR(OTsq|r$Kd}F;^HmK1*LGQth3+uUcf=*FRPSC6)o6DALo^MiX1!af$Z$td%c^hu{ z9d58q2Dg?SYR~Pphlyc7xBrPDx8|5Sb8_KQ_h+(j=FW0^PF5HSRvW$40LcDyK1msk$4ME{`FuWvvN?TWp9#~adN?E4-jFz_rc_B`tI43Yug}# z24@1AYLM`BpfBr}Q?UmD-hovGKoIe8%kqdz2yVmd;1+(y~vacP*|7!6C7^l7+L@UUOxLh@l>f+9?E64Hldp;v|S zJ`J-Z&BHR`g7V-g1ZQn^kqY`5DN31wWf!ZZ%_84P2VWS$O|w+JcBdqX_IQQvBts^} zb;`r=zsNG!O~fSaOSL?pG8So;vV_M+D%h#DSueZFd7;hb^|~@G;|G)r z*kAcZz>5JaUi$p*&AajD^{bno#b4gp+WK_s6EJaa4@*Xsb0ZZ}E%iA~B#m`gaUGUw zoA=SKeI4Y{|Jagqlh)L_VjZHB*4QS^NxQPA;4SV{2msy9G_W4&4CKac|`t zJVs+otX*rz(#d*)e#GB85Dq#BA8BtNTzYRDKAN2@PV=3jCx!qDJ{m*Wyn1itv7($}Mt-&^c zzdT`UeU`2rLqV?`sbHM}M!I*87UNW=ef4xP2K6l zsM91B$u^_)&Y}d|QW7V8Ah@sfjTw@;zC+Yvmh914`r`pFhNWr`Xij;;X43^-q`E#c ziKD~dx&q2gCC!9#c8fGubA*aMPYo@*j%wC$kN5VKH$y&+SuZn0?N^Jd8&s8%foyxFZOe|P|eL2o_jPtcd(o#qiq_F zieZ@1B$u_+4p+nOlF6_N>g&fK;tlQ779*iNAxSZm%H8KsQ-uqm8Z6DJprvx?!&EAp z(Hx99Ali`DAb{)JimzxlUQ(7cC%mC0=Z%EZtaw1XzH-cNZ)+jks5QK17lUeQT}+vv z%7=SCHpF)aLn?%_Gcl;8#(^f@F~D?S`XMx-(PUw-*|9y;fuC=`ihSq+Gyt3yz-R$? z>=p`e_mpbHF)8|S%rAlwUxhAO1giF)QMCtDt=VzvC3&w#vZ0z`o?3Zf&FnMte|FRh zUg*OKNZlA~orhzn&Fj$moW~l+bd=u9LRlET9&Gh9P}6B=gPx0AuuM8~^|S diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc deleted file mode 100644 index 388d17ce437d5e77c090d605e9ab7c6a1e59f902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8966 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 B+ynps diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc deleted file mode 100644 index 88c2e9b7e2197e117c73e010c6cadb299aa67230..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4756 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 Dj=$|a diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc b/env/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc deleted file mode 100644 index bf8bf8bb41dd49a78d48c521efffaa9a8be7fa01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 365 zcmYk1OHRWu5QgJ4eW+?x7D#Xex+qz&LPCf>QV~%cl+*=fGfHbCBAg~lY@uF&Q*Z&U z!7;pLl`F8qrXVrae4c;i*H|X~e%I3R@cIF7`u;THf7n`F>8wsPs6`RCG87}E>)57t z+@Ouvp-$YS&A3HdahtXyYuKr^+ZrM@NY+)(rC^X|MP7;;>3(gN)(r#4;79`xJE{xt zD1|H;Kxr(h9g*qOiz3zZ!Y~L`pWquD++*0w!<8Q{$#~)672seA^MK%)I=&0Nl^>7@ zCd6ONVCILv{sSDq?RYu8_M*M_-6{wAogaKnT#*%SkrpGlEt1VMqobE6#`x%5u6Jka u9XB%<(yd_SHsS7ur*0(@AuHJAlvSt2PIWG_oJ!6v%{Qx_M$dN8-}we$v0s4z diff --git a/env/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py b/env/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py deleted file mode 100644 index 329de602..00000000 --- a/env/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py +++ /dev/null @@ -1,164 +0,0 @@ -"""Logic that powers autocompletion installed by ``pip completion``. -""" - -import optparse -import os -import sys -from itertools import chain - -from pip._internal.cli.main_parser import create_main_parser -from pip._internal.commands import commands_dict, create_command -from pip._internal.utils.misc import get_installed_distributions -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Iterable, List, Optional - - -def autocomplete(): - # type: () -> None - """Entry Point for completion of main and subcommand options. - """ - # Don't complete if user hasn't sourced bash_completion file. - if 'PIP_AUTO_COMPLETE' not in os.environ: - return - cwords = os.environ['COMP_WORDS'].split()[1:] - cword = int(os.environ['COMP_CWORD']) - try: - current = cwords[cword - 1] - except IndexError: - current = '' - - parser = create_main_parser() - subcommands = list(commands_dict) - options = [] - - # subcommand - subcommand_name = None # type: Optional[str] - for word in cwords: - if word in subcommands: - subcommand_name = word - break - # subcommand options - if subcommand_name is not None: - # special case: 'help' subcommand has no options - if subcommand_name == 'help': - sys.exit(1) - # special case: list locally installed dists for show and uninstall - should_list_installed = ( - subcommand_name in ['show', 'uninstall'] and - not current.startswith('-') - ) - if should_list_installed: - installed = [] - lc = current.lower() - for dist in get_installed_distributions(local_only=True): - if dist.key.startswith(lc) and dist.key not in cwords[1:]: - installed.append(dist.key) - # if there are no dists installed, fall back to option completion - if installed: - for dist in installed: - print(dist) - sys.exit(1) - - subcommand = create_command(subcommand_name) - - for opt in subcommand.parser.option_list_all: - if opt.help != optparse.SUPPRESS_HELP: - for opt_str in opt._long_opts + opt._short_opts: - options.append((opt_str, opt.nargs)) - - # filter out previously specified options from available options - prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] - options = [(x, v) for (x, v) in options if x not in prev_opts] - # filter options by current input - options = [(k, v) for k, v in options if k.startswith(current)] - # get completion type given cwords and available subcommand options - completion_type = get_path_completion_type( - cwords, cword, subcommand.parser.option_list_all, - ) - # get completion files and directories if ``completion_type`` is - # ````, ``

    - FastAPI -